From b06329f47e432a78c68ebd6f72e94a1a49a53605 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 20 Jun 2024 16:40:46 -0700 Subject: [PATCH 001/248] Remove dotmap and pexpect from setup.py, they shouldn't be required --- meshtastic/__init__.py | 1 - setup.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 26d8e94..771f14e 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -77,7 +77,6 @@ from typing import * import google.protobuf.json_format import serial # type: ignore[import-untyped] import timeago # type: ignore[import-untyped] -from dotmap import DotMap # type: ignore[import-untyped] from google.protobuf.json_format import MessageToJson from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate diff --git a/setup.py b/setup.py index 6fb7477..cc77a5c 100644 --- a/setup.py +++ b/setup.py @@ -37,8 +37,6 @@ setup( "protobuf>=5.26.0", "requests>=2.25.0", "pypubsub>=4.0.3", - "dotmap>=1.3.14", - "pexpect>=4.6.0", "pyqrcode>=1.2.1", "tabulate>=0.8.9", "timeago>=1.0.15", From a1021c4f78ccf4be5360be11f070a8027135a5e4 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 20 Jun 2024 16:45:22 -0700 Subject: [PATCH 002/248] add dotmap back, that test file isn't in tests, it's in meshtastic.test, oops --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index cc77a5c..7aaacf9 100644 --- a/setup.py +++ b/setup.py @@ -37,6 +37,7 @@ setup( "protobuf>=5.26.0", "requests>=2.25.0", "pypubsub>=4.0.3", + "dotmap>=1.3.14", "pyqrcode>=1.2.1", "tabulate>=0.8.9", "timeago>=1.0.15", From 23f41bff0a988e545ab55ea963916c2afc7e0297 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 20 Jun 2024 16:51:55 -0700 Subject: [PATCH 003/248] Improve ACK handling: correctly pass them to `onAckNak` handlers, and add a mechanism for other handlers to request acks as well. --- meshtastic/__init__.py | 1 + meshtastic/mesh_interface.py | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 771f14e..a5075bc 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -127,6 +127,7 @@ class ResponseHandler(NamedTuple): # requestId: int - used only as a key callback: Callable + ackPermitted: bool = False # FIXME, add timestamp and age out old requests diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index b43d42e..5b3403c 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -296,6 +296,7 @@ class MeshInterface: # pylint: disable=R0902 wantAck: bool=False, wantResponse: bool=False, onResponse: Optional[Callable[[dict], Any]]=None, + onResponseAckPermitted: bool=False, channelIndex: int=0, ): """Send a data packet to some other node @@ -315,6 +316,10 @@ class MeshInterface: # pylint: disable=R0902 onResponse -- A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt) + onResponseAckPermitted -- should the onResponse callback be called + for regular ACKs (True) or just data responses & NAKs (False) + Note that if the onResponse callback is called 'onAckNak' this + will implicitly be true. channelIndex - channel number to use Returns the sent packet. The id field will be populated in this packet @@ -346,7 +351,7 @@ class MeshInterface: # pylint: disable=R0902 if onResponse is not None: logging.debug(f"Setting a response handler for requestId {meshPacket.id}") - self._addResponseHandler(meshPacket.id, onResponse) + self._addResponseHandler(meshPacket.id, onResponse, ackPermitted=onResponseAckPermitted) p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck) return p @@ -528,8 +533,8 @@ class MeshInterface: # pylint: disable=R0902 if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE': our_exit("No response from node. At least firmware 2.1.22 is required on the destination node.") - def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any]): - self.responseHandlers[requestId] = ResponseHandler(callback) + def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any], ackPermitted: bool=False): + self.responseHandlers[requestId] = ResponseHandler(callback=callback, ackPermitted=ackPermitted) def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False): """Send a MeshPacket to the specified node (or if unspecified, broadcast). @@ -1129,16 +1134,18 @@ class MeshInterface: # pylint: disable=R0902 requestId = decoded.get("requestId") if requestId is not None: logging.debug(f"Got a response for requestId {requestId}") - # We ignore ACK packets, but send NAKs and data responses to the handlers + # 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 routing = decoded.get("routing") isAck = routing is not None and ("errorReason" not in routing or routing["errorReason"] == "NONE") - if not isAck: - # we keep the responseHandler in dict until we get a non ack - handler = self.responseHandlers.pop(requestId, None) - if handler is not None: - if not isAck or (isAck and handler.__name__ == "onAckNak"): - logging.debug(f"Calling response handler for requestId {requestId}") - handler.callback(asDict) + # we keep the responseHandler in dict until we actually call it + handler = self.responseHandlers.get(requestId, None) + if handler is not None: + if (not isAck) or handler.callback.__name__ == "onAckNak" or handler.ackPermitted: + handler = self.responseHandlers.pop(requestId, None) + logging.debug(f"Calling response handler for requestId {requestId}") + handler.callback(asDict) logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") publishingThread.queueWork( From b5d1b7612fc3ffcfc29a2b9d613a3f035b81909b Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Mon, 3 Jun 2024 17:55:24 +0200 Subject: [PATCH 004/248] Replace timeago Replace the timeago library with a simple function --- meshtastic/__init__.py | 2 +- meshtastic/mesh_interface.py | 26 +++++++++++++++++++++----- setup.py | 1 - 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index a5075bc..313cb42 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -76,7 +76,7 @@ from typing import * import google.protobuf.json_format import serial # type: ignore[import-untyped] -import timeago # type: ignore[import-untyped] +from dotmap import DotMap # type: ignore[import-untyped] from google.protobuf.json_format import MessageToJson from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 5b3403c..bb04b74 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -14,7 +14,6 @@ from decimal import Decimal from typing import Any, Callable, Dict, List, Optional, Union import google.protobuf.json_format -import timeago # type: ignore[import-untyped] from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate @@ -158,11 +157,28 @@ class MeshInterface: # pylint: disable=R0902 def getTimeAgo(ts) -> Optional[str]: """Format how long ago have we heard from this node (aka timeago).""" - return ( - timeago.format(datetime.fromtimestamp(ts), datetime.now()) - if ts - else None + if ts is None: + return None + delta = datetime.now() - datetime.fromtimestamp(ts) + delta_secs = int(delta.total_seconds()) + if delta_secs < 0: + return None # not handling a timestamp from the future + intervals = ( + ("year", 60 * 60 * 24 * 365), + ("month", 60 * 60 * 24 * 30), + ("day", 60 * 60 * 24), + ("hour", 60 * 60), + ("min", 60), + ("sec", 1), ) + for name, interval_duration in intervals: + if delta_secs < interval_duration: + continue + x = delta_secs // interval_duration + plur = "s" if x > 1 else "" + return f"{x} {name}{plur} ago" + + return "now" rows: List[Dict[str, Any]] = [] if self.nodesByNum: diff --git a/setup.py b/setup.py index 7aaacf9..eed7c1c 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,6 @@ setup( "dotmap>=1.3.14", "pyqrcode>=1.2.1", "tabulate>=0.8.9", - "timeago>=1.0.15", "pyyaml", "bleak>=0.21.1", "packaging", From c34d08b0e53cd9c6e252d5e92b456f0566779ffc Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Fri, 21 Jun 2024 10:28:45 +0200 Subject: [PATCH 005/248] Refactor timeago and add tests _timeago is not specialized for mesh interfaces so it is factored out into a private function --- meshtastic/mesh_interface.py | 40 +++++++++++++++---------- meshtastic/tests/test_mesh_interface.py | 13 +++++++- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index bb04b74..66ce7f2 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -41,6 +41,29 @@ from meshtastic.util import ( ) +def _timeago(delta_secs: int) -> str: + """Convert a number of seconds in the past into a short, friendly string + e.g. "now", "30 sec ago", "1 hour ago" + Zero or negative intervals simply return "now" + """ + intervals = ( + ("year", 60 * 60 * 24 * 365), + ("month", 60 * 60 * 24 * 30), + ("day", 60 * 60 * 24), + ("hour", 60 * 60), + ("min", 60), + ("sec", 1), + ) + for name, interval_duration in intervals: + if delta_secs < interval_duration: + continue + x = delta_secs // interval_duration + plur = "s" if x > 1 else "" + return f"{x} {name}{plur} ago" + + return "now" + + class MeshInterface: # pylint: disable=R0902 """Interface class for meshtastic devices @@ -163,22 +186,7 @@ class MeshInterface: # pylint: disable=R0902 delta_secs = int(delta.total_seconds()) if delta_secs < 0: return None # not handling a timestamp from the future - intervals = ( - ("year", 60 * 60 * 24 * 365), - ("month", 60 * 60 * 24 * 30), - ("day", 60 * 60 * 24), - ("hour", 60 * 60), - ("min", 60), - ("sec", 1), - ) - for name, interval_duration in intervals: - if delta_secs < interval_duration: - continue - x = delta_secs // interval_duration - plur = "s" if x > 1 else "" - return f"{x} {name}{plur} ago" - - return "now" + return _timeago(delta_secs) rows: List[Dict[str, Any]] = [] if self.nodesByNum: diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 037e0bf..22950e5 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -7,7 +7,7 @@ from unittest.mock import MagicMock, patch import pytest from .. import mesh_pb2, config_pb2, BROADCAST_ADDR, LOCAL_ADDR -from ..mesh_interface import MeshInterface +from ..mesh_interface import MeshInterface, _timeago from ..node import Node # TODO @@ -684,3 +684,14 @@ def test_waitConnected_isConnected_timeout(capsys): out, err = capsys.readouterr() assert re.search(r"warn about something", err, re.MULTILINE) assert out == "" + + +@pytest.mark.unit +def test_timeago(): + assert _timeago(0) == "now" + assert _timeago(1) == "1 sec ago" + assert _timeago(15) == "15 secs ago" + assert _timeago(333) == "5 mins ago" + assert _timeago(99999) == "1 day ago" + assert _timeago(9999999) == "3 months ago" + assert _timeago(-999) == "now" From ccfb04720f95f5052409540f684e4f2eb96580e2 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 19 Jun 2024 14:45:59 -0700 Subject: [PATCH 006/248] Add a whitelist of known meshtastic USB VIDs to use a default serial ports. Initially only RAK4631 and heltec tracker are listed --- meshtastic/util.py | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index 14f6a54..86de1e9 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -24,8 +24,14 @@ import serial.tools.list_ports # type: ignore[import-untyped] from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version -"""Some devices such as a seger jlink we never want to accidentally open""" -blacklistVids = dict.fromkeys([0x1366]) +"""Some devices such as a seger jlink or st-link we never want to accidentally open""" +blacklistVids = dict.fromkeys([0x1366, 0x0483]) + +"""Some devices are highly likely to be meshtastic. +0x239a RAK4631 +0x303a Heltec tracker""" +whitelistVids = dict.fromkeys([0x239a, 0x303a]) + def quoteBooleans(a_string): """Quote booleans @@ -130,19 +136,35 @@ def findPorts(eliminate_duplicates: bool=False) -> List[str]: Returns: list -- a list of device paths """ - l = list( + all_ports = serial.tools.list_ports.comports() + + # look for 'likely' meshtastic devices + ports = list( map( lambda port: port.device, filter( - lambda port: port.vid is not None and port.vid not in blacklistVids, - serial.tools.list_ports.comports(), + lambda port: port.vid is not None and port.vid in whitelistVids, + all_ports, ), ) ) - l.sort() + + # if no likely devices, just list everything not blacklisted + if len(ports) == 0: + ports = list( + map( + lambda port: port.device, + filter( + lambda port: port.vid is not None and port.vid not in blacklistVids, + all_ports, + ), + ) + ) + + ports.sort() if eliminate_duplicates: - l = eliminate_duplicate_port(l) - return l + ports = eliminate_duplicate_port(ports) + return ports class dotdict(dict): From cd5913ae6d5306d02d471b90b9a3949839282657 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 27 Apr 2024 09:18:10 -0700 Subject: [PATCH 007/248] WIP switch to using Poetry for builds/dev usage. Looks pretty good still need to update readme and pypi upload --- .github/workflows/ci.yml | 15 +- bin/prerelease-tests.sh | 20 +- bin/run.sh | 2 - bin/test-release.sh | 6 +- bin/upload-release.sh | 7 +- poetry.lock | 1802 ++++++++++++++++++++++++++++++++++++++ pyproject.toml | 53 ++ requirements.txt | 30 - setup.py | 56 -- 9 files changed, 1880 insertions(+), 111 deletions(-) delete mode 100755 bin/run.sh create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8267aa..36e6c7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,21 +27,19 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip3 install -r requirements.txt + pip3 install poetry - name: Install meshtastic from local run: | - pip3 install . - which meshtastic - meshtastic --version + poetry run meshtastic --version - name: Run pylint - run: pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" + run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" - name: Check types with mypy run: mypy meshtastic/ - name: Run tests with pytest - run: pytest --cov=meshtastic + run: poetry run pytest --cov=meshtastic - name: Generate coverage report run: | - pytest --cov=meshtastic --cov-report=xml + poetry run pytest --cov=meshtastic --cov-report=xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: @@ -67,6 +65,5 @@ jobs: uses: actions/setup-python@v1 - name: Install meshtastic from local run: | - pip3 install . - which meshtastic + poetry install meshtastic --version diff --git a/bin/prerelease-tests.sh b/bin/prerelease-tests.sh index ab39881..8f89548 100755 --- a/bin/prerelease-tests.sh +++ b/bin/prerelease-tests.sh @@ -3,20 +3,24 @@ set -e # You may consider running: "pytest -m smoke1" instead of this test. echo "Running (crude) prerelease tests to verify sanity" + +# Use the python environment created by poetry +source $(poetry env info --path)/bin/activate + echo running hello python3 tests/hello_world.py -# bin/run.sh --help +# meshtastic --help echo toggling router -bin/run.sh --set is_router true -bin/run.sh --set is_router false +meshtastic --set is_router true +meshtastic --set is_router false # TODO: This does not seem to work. echo setting channel -bin/run.sh --seturl "https://www.meshtastic.org/c/#GAMiENTxuzogKQdZ8Lz_q89Oab8qB0RlZmF1bHQ=" +meshtastic --seturl "https://www.meshtastic.org/c/#GAMiENTxuzogKQdZ8Lz_q89Oab8qB0RlZmF1bHQ=" echo setting owner -bin/run.sh --set-owner "Test Build" +meshtastic --set-owner "Test Build" echo setting position -bin/run.sh --setlat 32.7767 --setlon -96.7970 --setalt 1337 +meshtastic --setlat 32.7767 --setlon -96.7970 --setalt 1337 echo dumping info -bin/run.sh --info +meshtastic run meshtastic --info echo sending closing message -bin/run.sh --sendtext "Sanity complete" +meshtastic --sendtext "Sanity complete" diff --git a/bin/run.sh b/bin/run.sh deleted file mode 100755 index 460c0fe..0000000 --- a/bin/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -rm log_* -python3 -m meshtastic "$@" diff --git a/bin/test-release.sh b/bin/test-release.sh index 333d1dc..d20f374 100755 --- a/bin/test-release.sh +++ b/bin/test-release.sh @@ -3,8 +3,6 @@ set -e bin/regen-docs.sh pandoc --from=markdown --to=rst --output=README README.md -python3 setup.py sdist bdist_wheel -python3 -m twine check dist/* -# test the upload -python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* + +poetry publish -r test-pypi --build echo "view the upload at https://test.pypi.org/ it it looks good upload for real" diff --git a/bin/upload-release.sh b/bin/upload-release.sh index f8a23ff..428a6ae 100755 --- a/bin/upload-release.sh +++ b/bin/upload-release.sh @@ -1,5 +1,8 @@ rm dist/* set -e -python3 setup.py sdist bdist_wheel -python3 -m twine upload dist/* +poetry build +poetry run pytest +poetry publish +#python3 setup.py sdist bdist_wheel +#python3 -m twine upload dist/* diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..187f251 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1802 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "astroid" +version = "2.15.8" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, + {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +wrapt = [ + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, +] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "autopep8" +version = "2.3.0" +description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" +optional = false +python-versions = ">=3.8" +files = [ + {file = "autopep8-2.3.0-py2.py3-none-any.whl", hash = "sha256:b716efa70cbafbf4a2c9c5ec1cabfa037a68f9e30b04c74ffa5864dd49b8f7d2"}, + {file = "autopep8-2.3.0.tar.gz", hash = "sha256:5cfe45eb3bef8662f6a3c7e28b7c0310c7310d340074b7f0f28f9810b44b7ef4"}, +] + +[package.dependencies] +pycodestyle = ">=2.12.0" +tomli = {version = "*", markers = "python_version < \"3.11\""} + +[[package]] +name = "bleak" +version = "0.21.1" +description = "Bluetooth Low Energy platform Agnostic Klient" +optional = false +python-versions = ">=3.8,<3.13" +files = [ + {file = "bleak-0.21.1-py3-none-any.whl", hash = "sha256:ccec260a0f5ec02dd133d68b0351c0151b2ecf3ddd0bcabc4c04a1cdd7f33256"}, + {file = "bleak-0.21.1.tar.gz", hash = "sha256:ec4a1a2772fb315b992cbaa1153070c7e26968a52b0e2727035f443a1af5c18f"}, +] + +[package.dependencies] +async-timeout = {version = ">=3.0.0,<5", markers = "python_version < \"3.11\""} +bleak-winrt = {version = ">=1.2.0,<2.0.0", markers = "platform_system == \"Windows\" and python_version < \"3.12\""} +dbus-fast = {version = ">=1.83.0,<3", markers = "platform_system == \"Linux\""} +pyobjc-core = {version = ">=9.2,<10.0", markers = "platform_system == \"Darwin\""} +pyobjc-framework-CoreBluetooth = {version = ">=9.2,<10.0", markers = "platform_system == \"Darwin\""} +pyobjc-framework-libdispatch = {version = ">=9.2,<10.0", markers = "platform_system == \"Darwin\""} +typing-extensions = {version = ">=4.7.0", markers = "python_version < \"3.12\""} +"winrt-Windows.Devices.Bluetooth" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Devices.Bluetooth.Advertisement" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Devices.Bluetooth.GenericAttributeProfile" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Devices.Enumeration" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Foundation" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Foundation.Collections" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} +"winrt-Windows.Storage.Streams" = {version = "2.0.0b1", markers = "platform_system == \"Windows\" and python_version >= \"3.12\""} + +[[package]] +name = "bleak-winrt" +version = "1.2.0" +description = "Python WinRT bindings for Bleak" +optional = false +python-versions = "*" +files = [ + {file = "bleak-winrt-1.2.0.tar.gz", hash = "sha256:0577d070251b9354fc6c45ffac57e39341ebb08ead014b1bdbd43e211d2ce1d6"}, + {file = "bleak_winrt-1.2.0-cp310-cp310-win32.whl", hash = "sha256:a2ae3054d6843ae0cfd3b94c83293a1dfd5804393977dd69bde91cb5099fc47c"}, + {file = "bleak_winrt-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:677df51dc825c6657b3ae94f00bd09b8ab88422b40d6a7bdbf7972a63bc44e9a"}, + {file = "bleak_winrt-1.2.0-cp311-cp311-win32.whl", hash = "sha256:9449cdb942f22c9892bc1ada99e2ccce9bea8a8af1493e81fefb6de2cb3a7b80"}, + {file = "bleak_winrt-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:98c1b5a6a6c431ac7f76aa4285b752fe14a1c626bd8a1dfa56f66173ff120bee"}, + {file = "bleak_winrt-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:623ac511696e1f58d83cb9c431e32f613395f2199b3db7f125a3d872cab968a4"}, + {file = "bleak_winrt-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:13ab06dec55469cf51a2c187be7b630a7a2922e1ea9ac1998135974a7239b1e3"}, + {file = "bleak_winrt-1.2.0-cp38-cp38-win32.whl", hash = "sha256:5a36ff8cd53068c01a795a75d2c13054ddc5f99ce6de62c1a97cd343fc4d0727"}, + {file = "bleak_winrt-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:810c00726653a962256b7acd8edf81ab9e4a3c66e936a342ce4aec7dbd3a7263"}, + {file = "bleak_winrt-1.2.0-cp39-cp39-win32.whl", hash = "sha256:dd740047a08925bde54bec357391fcee595d7b8ca0c74c87170a5cbc3f97aa0a"}, + {file = "bleak_winrt-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:63130c11acfe75c504a79c01f9919e87f009f5e742bfc7b7a5c2a9c72bf591a7"}, +] + +[[package]] +name = "certifi" +version = "2024.6.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.5.3" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, + {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, + {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, + {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, + {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, + {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, + {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, + {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, + {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, + {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, + {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, + {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, + {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, + {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, + {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, + {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, + {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, + {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, + {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, + {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, + {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, + {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "dbus-fast" +version = "2.21.3" +description = "A faster version of dbus-next" +optional = false +python-versions = "<4.0,>=3.7" +files = [ + {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:828f2a337eac4c3b24b43ab4edc8d8bc656f558a4f07aa2b173e007ce093bd49"}, + {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b379ed7ef0d174480e41a5f1dde3392d974e618bb91e5fbfa06396c24d3c80fc"}, + {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:990d60e9796fa142e16af331e53d91aaa94dfbcf37b474c1d6caf61310fcc5ee"}, + {file = "dbus_fast-2.21.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9d0bbfa7cdb440f13d58e13625344b918b70ff0ccddc20ddd9c0ebf3e5a765dd"}, + {file = "dbus_fast-2.21.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0d4f459ba4fa394e3ba22a7421055878953aa92efd01e3a1d5216519c6b1586c"}, + {file = "dbus_fast-2.21.3-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:61d20cecc3efdc0e75bb7d5f4ae18929559003644b32945bfaa93b7e06cd94b6"}, + {file = "dbus_fast-2.21.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d53f5b24c732af5ae9c7e88fc9ba687ce2a785c63dcea3b9c984619f1bdcf71a"}, + {file = "dbus_fast-2.21.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b5ef802b2b7e5dbebdfa338a0278e5212a6073c26764c75f3e373e2a9b01797c"}, + {file = "dbus_fast-2.21.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:251d46d0d7cbed0d9b9eac2f91f6669893db9b87e19defb99f9a85579c2f786a"}, + {file = "dbus_fast-2.21.3-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:0665d8cb179f0b8fff23e63592c1f454fdaa4ae44a4263a7a7b7df8d834b3f71"}, + {file = "dbus_fast-2.21.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ca29609a31f816c315844ed41b81247e3114261d26e5ee1dcc85bf5c046a36"}, + {file = "dbus_fast-2.21.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b520792549e8b2b1e4c8777492783ba81065bd02e16e4390e2b299bf33f1feea"}, + {file = "dbus_fast-2.21.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f44d2ea35daefac7ad1ede65695fde18526fb38f9ec0aadf108f629bb6c87293"}, + {file = "dbus_fast-2.21.3-cp37-cp37m-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:50aa62f63de3e591d739b4925816b84f4169e9086701a2722a5e7a1f6f273bc0"}, + {file = "dbus_fast-2.21.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8fad077a989b002602aa192cfa95b89b3e40c5fa6da7740f42a87488bdbed6f"}, + {file = "dbus_fast-2.21.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87e8db4ea5023024a638826321039497dcbc7e70583bd33743eac2d8e69ca4fb"}, + {file = "dbus_fast-2.21.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0c342d8b33079c550ea575344d53807f6ae6464b1a5f6f9e0523fae979198872"}, + {file = "dbus_fast-2.21.3-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:41d6f81a5226e90f1bde95ce90a63430f58aea0c300f034b4055a7bfae187031"}, + {file = "dbus_fast-2.21.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d76b512cc8db4ebdfb7879d7cae42ee0adc362671bc0a4f55df5f4ebe547602d"}, + {file = "dbus_fast-2.21.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9fdbe2b22668f4021e909e65fa6a25bca1ab08294a35c600af95ba06a2f2d101"}, + {file = "dbus_fast-2.21.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:638c4b64159f8a3567e38705246bd1a2625d8c9adbb7ffa23a6a2ec2dfd40db0"}, + {file = "dbus_fast-2.21.3-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:dadc4bdcbe808f0d1750f951b3b4211763f280116714cb9749ebae2262bdc49c"}, + {file = "dbus_fast-2.21.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83e0a28e04218493ebd66c1f2a5290203ffff924ec01b37c5128ba1fa9731255"}, + {file = "dbus_fast-2.21.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:846733011edad8c0125f2b1148783c8d2ae162419707bb7e2bf08a26040939d8"}, + {file = "dbus_fast-2.21.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:07213240465c3c7306705ad512c983ada45ef222d2eecf3d7ab19f397b02de0d"}, + {file = "dbus_fast-2.21.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8bfea9007a654adc5c16d43d124fded0c788fdb2a6e2c470fcfd7d0076bda87e"}, + {file = "dbus_fast-2.21.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5b202ffd4314c82f68b2431d928d596c45def381c018832003045f19ed857a"}, + {file = "dbus_fast-2.21.3-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:19091565dd9b5db9b3fa82459361c459387c01b11a656f36cab6a73284300c8c"}, + {file = "dbus_fast-2.21.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa74eb299ec88319a6a46c9b59aeebf9782378d9724913bcb3fb746a3222f70a"}, + {file = "dbus_fast-2.21.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:2bb2a659f31e1af87a3c4e41af3af69cb5a2bb4a335b35d8d6e80b43e8aed8e9"}, + {file = "dbus_fast-2.21.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56bf648a329257b127ee05667451e929c50ada7117737d14341a5399ca7860e1"}, + {file = "dbus_fast-2.21.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:4bb07da46377b7affe648ce34ac42fb3409e87b40b55d64f0fd23512e583ce46"}, + {file = "dbus_fast-2.21.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b07d22e167b0af834344bd1c8619b702b823d8989d6884fc9719c6e871c413f5"}, + {file = "dbus_fast-2.21.3.tar.gz", hash = "sha256:8d0f0f61d007c1316ce79cde35ed52c0ce8ce229fd0f0bf8c9af2013ab4516a7"}, +] + +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "dotmap" +version = "1.3.30" +description = "ordered, dynamically-expandable dot-access dictionary" +optional = false +python-versions = "*" +files = [ + {file = "dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6"}, + {file = "dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "hypothesis" +version = "6.103.2" +description = "A library for property-based testing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "hypothesis-6.103.2-py3-none-any.whl", hash = "sha256:629b7cdeca8c225933739f99879caba21949000d2c919c8b4585e01048b3bc73"}, + {file = "hypothesis-6.103.2.tar.gz", hash = "sha256:83504e31e90a0d7d6e8eb93e51525dc1a48d79c932a50ad6035e29f8295328cd"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +sortedcontainers = ">=2.1.0,<3.0.0" + +[package.extras] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.54)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] +cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] +codemods = ["libcst (>=0.3.16)"] +crosshair = ["crosshair-tool (>=0.0.54)", "hypothesis-crosshair (>=0.0.4)"] +dateutil = ["python-dateutil (>=1.4)"] +django = ["django (>=3.2)"] +dpcontracts = ["dpcontracts (>=0.4)"] +ghostwriter = ["black (>=19.10b0)"] +lark = ["lark (>=0.10.1)"] +numpy = ["numpy (>=1.17.3)"] +pandas = ["pandas (>=1.1)"] +pytest = ["pytest (>=4.6)"] +pytz = ["pytz (>=2014.1)"] +redis = ["redis (>=3.0.0)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2024.1)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "importlib-metadata" +version = "7.2.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, + {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "lazy-object-proxy" +version = "1.10.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, +] + +[[package]] +name = "mako" +version = "1.3.5" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, + {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markdown" +version = "3.6" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "modbus-tk" +version = "1.1.3" +description = "Implementation of modbus protocol in python" +optional = false +python-versions = "*" +files = [ + {file = "modbus_tk-1.1.3-py3-none-any.whl", hash = "sha256:2b7afca05292a58371e7a7e4ec2931f2bb9b8a1a7c0295ada758740e72985aef"}, + {file = "modbus_tk-1.1.3.tar.gz", hash = "sha256:690fa7bb86ea978992465d2d61c8b5acc639ce0e8b833a0aa96d4dd172c5644a"}, +] + +[package.dependencies] +pyserial = ">=3.1" + +[[package]] +name = "mypy" +version = "1.10.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c"}, + {file = "mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + +[[package]] +name = "numpy" +version = "2.0.0" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787"}, + {file = "numpy-2.0.0-cp310-cp310-win32.whl", hash = "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98"}, + {file = "numpy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f"}, + {file = "numpy-2.0.0-cp311-cp311-win32.whl", hash = "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f"}, + {file = "numpy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"}, + {file = "numpy-2.0.0-cp312-cp312-win32.whl", hash = "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54"}, + {file = "numpy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44"}, + {file = "numpy-2.0.0-cp39-cp39-win32.whl", hash = "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275"}, + {file = "numpy-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9"}, + {file = "numpy-2.0.0.tar.gz", hash = "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pdoc3" +version = "0.10.0" +description = "Auto-generate API documentation for Python projects." +optional = false +python-versions = ">= 3.6" +files = [ + {file = "pdoc3-0.10.0-py3-none-any.whl", hash = "sha256:ba45d1ada1bd987427d2bf5cdec30b2631a3ff5fb01f6d0e77648a572ce6028b"}, + {file = "pdoc3-0.10.0.tar.gz", hash = "sha256:5f22e7bcb969006738e1aa4219c75a32f34c2d62d46dc9d2fb2d3e0b0287e4b7"}, +] + +[package.dependencies] +mako = "*" +markdown = ">=3.0" + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "protobuf" +version = "5.27.1" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.27.1-cp310-abi3-win32.whl", hash = "sha256:3adc15ec0ff35c5b2d0992f9345b04a540c1e73bfee3ff1643db43cc1d734333"}, + {file = "protobuf-5.27.1-cp310-abi3-win_amd64.whl", hash = "sha256:25236b69ab4ce1bec413fd4b68a15ef8141794427e0b4dc173e9d5d9dffc3bcd"}, + {file = "protobuf-5.27.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e38fc29d7df32e01a41cf118b5a968b1efd46b9c41ff515234e794011c78b17"}, + {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:917ed03c3eb8a2d51c3496359f5b53b4e4b7e40edfbdd3d3f34336e0eef6825a"}, + {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:ee52874a9e69a30271649be88ecbe69d374232e8fd0b4e4b0aaaa87f429f1631"}, + {file = "protobuf-5.27.1-cp38-cp38-win32.whl", hash = "sha256:7a97b9c5aed86b9ca289eb5148df6c208ab5bb6906930590961e08f097258107"}, + {file = "protobuf-5.27.1-cp38-cp38-win_amd64.whl", hash = "sha256:f6abd0f69968792da7460d3c2cfa7d94fd74e1c21df321eb6345b963f9ec3d8d"}, + {file = "protobuf-5.27.1-cp39-cp39-win32.whl", hash = "sha256:dfddb7537f789002cc4eb00752c92e67885badcc7005566f2c5de9d969d3282d"}, + {file = "protobuf-5.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:39309898b912ca6febb0084ea912e976482834f401be35840a008da12d189340"}, + {file = "protobuf-5.27.1-py3-none-any.whl", hash = "sha256:4ac7249a1530a2ed50e24201d6630125ced04b30619262f06224616e0030b6cf"}, + {file = "protobuf-5.27.1.tar.gz", hash = "sha256:df5e5b8e39b7d1c25b186ffdf9f44f40f810bbcc9d2b71d9d3156fee5a9adf15"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pycodestyle" +version = "2.12.0" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.12.0-py2.py3-none-any.whl", hash = "sha256:949a39f6b86c3e1515ba1787c2022131d165a8ad271b11370a8819aa070269e4"}, + {file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"}, +] + +[[package]] +name = "pylint" +version = "2.17.7" +description = "python code static checker" +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, + {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, +] + +[package.dependencies] +astroid = ">=2.15.8,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pyobjc-core" +version = "9.2" +description = "Python<->ObjC Interoperability Module" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyobjc-core-9.2.tar.gz", hash = "sha256:d734b9291fec91ff4e3ae38b9c6839debf02b79c07314476e87da8e90b2c68c3"}, + {file = "pyobjc_core-9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fa674a39949f5cde8e5c7bbcd24496446bfc67592b028aedbec7f81dc5fc4daa"}, + {file = "pyobjc_core-9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bbc8de304ee322a1ee530b4d2daca135a49b4a49aa3cedc6b2c26c43885f4842"}, + {file = "pyobjc_core-9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0fa950f092673883b8bd28bc18397415cabb457bf410920762109b411789ade9"}, + {file = "pyobjc_core-9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:586e4cae966282eaa61b21cae66ccdcee9d69c036979def26eebdc08ddebe20f"}, + {file = "pyobjc_core-9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:41189c2c680931c0395a55691763c481fc681f454f21bb4f1644f98c24a45954"}, + {file = "pyobjc_core-9.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:2d23ee539f2ba5e9f5653d75a13f575c7e36586fc0086792739e69e4c2617eda"}, + {file = "pyobjc_core-9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b9809cf96678797acb72a758f34932fe8e2602d5ab7abec15c5ac68ddb481720"}, +] + +[[package]] +name = "pyobjc-framework-cocoa" +version = "9.2" +description = "Wrappers for the Cocoa frameworks on macOS" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyobjc-framework-Cocoa-9.2.tar.gz", hash = "sha256:efd78080872d8c8de6c2b97e0e4eac99d6203a5d1637aa135d071d464eb2db53"}, + {file = "pyobjc_framework_Cocoa-9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9e02d8a7cc4eb7685377c50ba4f17345701acf4c05b1e7480d421bff9e2f62a4"}, + {file = "pyobjc_framework_Cocoa-9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3b1e6287b3149e4c6679cdbccd8e9ef6557a4e492a892e80a77df143f40026d2"}, + {file = "pyobjc_framework_Cocoa-9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:312977ce2e3989073c6b324c69ba24283de206fe7acd6dbbbaf3e29238a22537"}, + {file = "pyobjc_framework_Cocoa-9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aae7841cf40c26dd915f4dd828f91c6616e6b7998630b72e704750c09e00f334"}, + {file = "pyobjc_framework_Cocoa-9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:739a421e14382a46cbeb9a883f192dceff368ad28ec34d895c48c0ad34cf2c1d"}, + {file = "pyobjc_framework_Cocoa-9.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:32d9ac1033fac1b821ddee8c68f972a7074ad8c50bec0bea9a719034c1c2fb94"}, + {file = "pyobjc_framework_Cocoa-9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b236bb965e41aeb2e215d4e98a5a230d4b63252c6d26e00924ea2e69540a59d6"}, +] + +[package.dependencies] +pyobjc-core = ">=9.2" + +[[package]] +name = "pyobjc-framework-corebluetooth" +version = "9.2" +description = "Wrappers for the framework CoreBluetooth on macOS" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyobjc-framework-CoreBluetooth-9.2.tar.gz", hash = "sha256:cb2481b1dfe211ae9ce55f36537dc8155dbf0dc8ff26e0bc2e13f7afb0a291d1"}, + {file = "pyobjc_framework_CoreBluetooth-9.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:53d888742119d0f0c725d0b0c2389f68e8f21f0cba6d6aec288c53260a0196b6"}, + {file = "pyobjc_framework_CoreBluetooth-9.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:179532882126526e38fe716a50fb0ee8f440e0b838d290252c515e622b5d0e49"}, + {file = "pyobjc_framework_CoreBluetooth-9.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:256a5031ea9d8a7406541fa1b0dfac549b1de93deae8284605f9355b13fb58be"}, +] + +[package.dependencies] +pyobjc-core = ">=9.2" +pyobjc-framework-Cocoa = ">=9.2" + +[[package]] +name = "pyobjc-framework-libdispatch" +version = "9.2" +description = "Wrappers for libdispatch on macOS" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyobjc-framework-libdispatch-9.2.tar.gz", hash = "sha256:542e7f7c2b041939db5ed6f3119c1d67d73ec14a996278b92485f8513039c168"}, + {file = "pyobjc_framework_libdispatch-9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88d4091d4bcb5702783d6e86b4107db973425a17d1de491543f56bd348909b60"}, + {file = "pyobjc_framework_libdispatch-9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1a67b007113328538b57893cc7829a722270764cdbeae6d5e1460a1d911314df"}, + {file = "pyobjc_framework_libdispatch-9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6fccea1a57436cf1ac50d9ebc6e3e725bcf77f829ba6b118e62e6ed7866d359d"}, + {file = "pyobjc_framework_libdispatch-9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6eba747b7ad91b0463265a7aee59235bb051fb97687f35ca2233690369b5e4e4"}, + {file = "pyobjc_framework_libdispatch-9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e835495860d04f63c2d2f73ae3dd79da4222864c107096dc0f99e8382700026"}, + {file = "pyobjc_framework_libdispatch-9.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1b107e5c3580b09553030961ea6b17abad4a5132101eab1af3ad2cb36d0f08bb"}, + {file = "pyobjc_framework_libdispatch-9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:83cdb672acf722717b5ecf004768f215f02ac02d7f7f2a9703da6e921ab02222"}, +] + +[package.dependencies] +pyobjc-core = ">=9.2" + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pypubsub" +version = "4.0.3" +description = "Python Publish-Subscribe Package" +optional = false +python-versions = ">=3.3, <4" +files = [ + {file = "Pypubsub-4.0.3-py3-none-any.whl", hash = "sha256:7f716bae9388afe01ff82b264ba8a96a8ae78b42bb1f114f2716ca8f9e404e2a"}, +] + +[[package]] +name = "pyqrcode" +version = "1.2.1" +description = "A QR code generator written purely in Python with SVG, EPS, PNG and terminal output." +optional = false +python-versions = "*" +files = [ + {file = "PyQRCode-1.2.1.tar.gz", hash = "sha256:fdbf7634733e56b72e27f9bce46e4550b75a3a2c420414035cae9d9d26b234d5"}, + {file = "PyQRCode-1.2.1.zip", hash = "sha256:1b2812775fa6ff5c527977c4cd2ccb07051ca7d0bc0aecf937a43864abe5eff6"}, +] + +[package.extras] +png = ["pypng (>=0.0.13)"] + +[[package]] +name = "pyserial" +version = "3.5" +description = "Python Serial Port Extension" +optional = false +python-versions = "*" +files = [ + {file = "pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"}, + {file = "pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb"}, +] + +[package.extras] +cp2110 = ["hidapi"] + +[[package]] +name = "pytap2" +version = "2.3.0" +description = "Object-oriented wrapper around the Linux Tun/Tap device" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytap2-2.3.0-py3-none-any.whl", hash = "sha256:a1edc287cf25c61f8fa8415fb6b61e50ac119ef5cd758ce15f2105d2c69f24ef"}, + {file = "pytap2-2.3.0.tar.gz", hash = "sha256:5a90d7b7c7107a438e53c7b27c1baadffe72889ada6024c02d19801fece2c383"}, +] + +[[package]] +name = "pytest" +version = "8.2.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "riden" +version = "1.2.0" +description = "A python library for Riden RD power supplies" +optional = false +python-versions = ">=3.7,<4.0" +files = [] +develop = false + +[package.dependencies] +click = "^8.0.3" +modbus_tk = "^1.1.2" +pyserial = "^3.5" + +[package.source] +type = "git" +url = "https://github.com/shaybox/riden.git" +reference = "HEAD" +resolved_reference = "ecbda543cf566346dd28558d957b4aa7fe116a83" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +optional = false +python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + +[[package]] +name = "timeago" +version = "1.0.16" +description = "A very simple python library, used to format datetime with `*** time ago` statement. eg: \"3 hours ago\"." +optional = false +python-versions = "*" +files = [ + {file = "timeago-1.0.16-py3-none-any.whl", hash = "sha256:9b8cb2e3102b329f35a04aa4531982d867b093b19481cfbb1dac7845fa2f79b0"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.12.5" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, +] + +[[package]] +name = "types-protobuf" +version = "5.26.0.20240422" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-protobuf-5.26.0.20240422.tar.gz", hash = "sha256:e6074178109f97efe9f0b20a035ba61d7c3b03e867eb47d254d2b2ab6a805e36"}, + {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20240311" +description = "Typing stubs for PyYAML" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-PyYAML-6.0.12.20240311.tar.gz", hash = "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342"}, + {file = "types_PyYAML-6.0.12.20240311-py3-none-any.whl", hash = "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"}, +] + +[[package]] +name = "types-requests" +version = "2.32.0.20240602" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-requests-2.32.0.20240602.tar.gz", hash = "sha256:3f98d7bbd0dd94ebd10ff43a7fbe20c3b8528acace6d8efafef0b6a184793f06"}, + {file = "types_requests-2.32.0.20240602-py3-none-any.whl", hash = "sha256:ed3946063ea9fbc6b5fc0c44fa279188bae42d582cb63760be6cb4b9d06c3de8"}, +] + +[package.dependencies] +urllib3 = ">=2" + +[[package]] +name = "types-setuptools" +version = "69.5.0.20240522" +description = "Typing stubs for setuptools" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-setuptools-69.5.0.20240522.tar.gz", hash = "sha256:c5a97601b2d040d3b9fcd0633730f0a8c86ebef208552525c97301427f261549"}, + {file = "types_setuptools-69.5.0.20240522-py3-none-any.whl", hash = "sha256:e27231cbc80648cfaee4921d2f1150107fdf8d33666958abf2aba0191a82688b"}, +] + +[[package]] +name = "types-tabulate" +version = "0.9.0.20240106" +description = "Typing stubs for tabulate" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-tabulate-0.9.0.20240106.tar.gz", hash = "sha256:c9b6db10dd7fcf55bd1712dd3537f86ddce72a08fd62bb1af4338c7096ce947e"}, + {file = "types_tabulate-0.9.0.20240106-py3-none-any.whl", hash = "sha256:0378b7b6fe0ccb4986299496d027a6d4c218298ecad67199bbd0e2d7e9d335a1"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "winrt-runtime" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-runtime-2.0.0b1.tar.gz", hash = "sha256:28db2ebe7bfb347d110224e9f23fe8079cea45af0fcbd643d039524ced07d22c"}, + {file = "winrt_runtime-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:8f812b01e2c8dd3ca68aa51a7aa02e815cc2ac3c8520a883b4ec7a4fc63afb04"}, + {file = "winrt_runtime-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:f36f6102f9b7a08d917a6809117c085639b66be2c579f4089d3fd47b83e8f87b"}, + {file = "winrt_runtime-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:4a99f267da96edc977623355b816b46c1344c66dc34732857084417d8cf9a96b"}, + {file = "winrt_runtime-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:ba998e3fc452338c5e2d7bf5174a6206580245066d60079ee4130082d0eb61c2"}, + {file = "winrt_runtime-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:e7838f0fdf5653ce245888590214177a1f54884cece2c8dfbfe3d01b2780171e"}, + {file = "winrt_runtime-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:2afa45b7385e99a63d55ccda29096e6a84fcd4c654479005c147b0e65e274abf"}, + {file = "winrt_runtime-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:edda124ff965cec3a6bfdb26fbe88e004f96975dd84115176e30c1efbcb16f4c"}, + {file = "winrt_runtime-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:d8935951efeec6b3d546dce8f48bb203aface57a1ba991c066f0e12e84c8f91e"}, + {file = "winrt_runtime-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:509fb9a03af5e1125433f58522725716ceef040050d33625460b5a5eb98a46ac"}, + {file = "winrt_runtime-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:41138fe4642345d7143e817ce0905d82e60b3832558143e0a17bfea8654c6512"}, + {file = "winrt_runtime-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:081a429fe85c33cb6610c4a799184b7650b30f15ab1d89866f2bda246d3a5c0a"}, + {file = "winrt_runtime-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:e6984604c6ae1f3258973ba2503d1ea5aa15e536ca41d6a131ad305ebbb6519d"}, +] + +[[package]] +name = "winrt-windows-devices-bluetooth" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Devices.Bluetooth-2.0.0b1.tar.gz", hash = "sha256:786bd43786b873a083b89debece538974f720584662a2573d6a8a8501a532860"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:79631bf3f96954da260859df9228a028835ffade0d885ba3942c5a86a853d150"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:cd85337a95065d0d2045c06db1a5edd4a447aad47cf7027818f6fb69f831c56c"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:6a963869ed003d260e90e9bedc334129303f263f068ea1c0d994df53317db2bc"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:7c5951943a3911d94a8da190f4355dc70128d7d7f696209316372c834b34d462"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:b0bb154ae92235649ed234982f609c490a467d5049c27d63397be9abbb00730e"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:6688dfb0fc3b7dc517bf8cf40ae00544a50b4dec91470d37be38fc33c4523632"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:613c6ff4125df46189b3bef6d3110d94ec725d357ab734f00eedb11c4116c367"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:59c403b64e9f4e417599c6f6aea6ee6fac960597c21eac6b3fd8a84f64aa387c"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:b7f6e1b9bb6e33be80045adebd252cf25cd648759fad6e86c61a393ddd709f7f"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:eae7a89106eab047e96843e28c3c6ce0886dd7dee60180a1010498925e9503f9"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:8dfd1915c894ac19dd0b24aba38ef676c92c3473c0d9826762ba9616ad7df68b"}, + {file = "winrt_Windows.Devices.Bluetooth-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:49058587e6d82ba33da0767b97a378ddfea8e3a5991bdeff680faa287bfae57e"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Devices.Bluetooth.GenericAttributeProfile[all] (==2.0.0-beta.1)", "winrt-Windows.Devices.Bluetooth.Rfcomm[all] (==2.0.0-beta.1)", "winrt-Windows.Devices.Enumeration[all] (==2.0.0-beta.1)", "winrt-Windows.Devices.Radios[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Networking[all] (==2.0.0-beta.1)", "winrt-Windows.Storage.Streams[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-devices-bluetooth-advertisement" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Devices.Bluetooth.Advertisement-2.0.0b1.tar.gz", hash = "sha256:d9050faa4377d410d4f0e9cabb5ec555a267531c9747370555ac9ec93ec9f399"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:ac9b703d16adc87c3541585525b8fcf6d84391e2fa010c2f001e714c405cc3b7"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:593cade7853a8b0770e8ef30462b5d5f477b82e17e0aa590094b1c26efd3e05a"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:574698c08895e2cfee7379bdf34a5f319fe440d7dfcc7bc9858f457c08e9712c"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:652a096f8210036bbb539d7f971eaf1f472a3aeb60b7e31278e3d0d30a355292"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:e5cfb866c44dad644fb44b441f4fdbddafc9564075f1f68f756e20f438105c67"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:6c2503eaaf5cd988b5510b86347dba45ad6ee52656f9656a1a97abae6d35386e"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:780c766725a55f4211f921c773c92c2331803e70f65d6ad6676a60f903d39a54"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:39c8633d01039eb2c2f6f20cfc43c045a333b9f3a45229e2ce443f71bb2a562c"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:eaa0d44b4158b16937eac8102249e792f0299dbb0aefc56cc9adc9552e8f9afe"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:d171487e23f7671ad2923544bfa6545d0a29a1a9ae1f5c1d5e5e5f473a5d62b2"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:442eecac87653a03617e65bdb2ef79ddc0582dfdacc2be8af841fba541577f8b"}, + {file = "winrt_Windows.Devices.Bluetooth.Advertisement-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:b30ab9b8c1ecf818be08bac86bee425ef40f75060c4011d4e6c2e624a7b9916e"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Devices.Bluetooth[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Storage.Streams[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-devices-bluetooth-genericattributeprofile" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1.tar.gz", hash = "sha256:93b745d51ecfb3e9d3a21623165cc065735c9e0146cb7a26744182c164e63e14"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:db740aaedd80cca5b1a390663b26c7733eb08f4c57ade6a04b055d548e9d042b"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:7c81aa6c066cdab58bcc539731f208960e094a6d48b59118898e1e804dbbdf7f"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:92277a6bbcbe2225ad1be92968af597dc77bc37a63cd729690d2d9fb5094ae25"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:6b48209669c1e214165530793cf9916ae44a0ae2618a9be7a489e8c94f7e745f"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:2f17216e6ce748eaef02fb0658213515d3ff31e2dbb18f070a614876f818c90d"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:db798a0f0762e390da5a9f02f822daff00692bd951a492224bf46782713b2938"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:b8d9dba04b9cfa53971c35117fc3c68c94bfa5e2ed18ce680f731743598bf246"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:e5260b3f33dee8a896604297e05efc04d04298329c205a74ded8e2d6333e84b7"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:822ef539389ecb546004345c4dce8b9b7788e2e99a1d6f0947a4b123dceb7fed"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:11e6863e7a94d2b6dd76ddcd19c01e311895810a4ce6ad08c7b5534294753243"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:20de8d04c301c406362c93e78d41912aea0af23c4b430704aba329420d7c2cdf"}, + {file = "winrt_Windows.Devices.Bluetooth.GenericAttributeProfile-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:918059796f2f123216163b928ecde8ecec17994fb7a94042af07fda82c132a6d"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Devices.Bluetooth[all] (==2.0.0-beta.1)", "winrt-Windows.Devices.Enumeration[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Storage.Streams[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-devices-enumeration" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Devices.Enumeration-2.0.0b1.tar.gz", hash = "sha256:8f214040e4edbe57c4943488887db89f4a00d028c34169aafd2205e228026100"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:dcb9e7d230aefec8531a46d393ecb1063b9d4b97c9f3ff2fc537ce22bdfa2444"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:22a3e1fef40786cc8d51320b6f11ff25de6c674475f3ba608a46915e1dadf0f5"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:2edcfeb70a71d40622873cad96982a28e92a7ee71f33968212dd3598b2d8d469"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:ce4eb88add7f5946d2666761a97a3bb04cac2a061d264f03229c1e15dbd7ce91"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:a9001f17991572abdddab7ab074e08046e74e05eeeaf3b2b01b8b47d2879b64c"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:0440b91ce144111e207f084cec6b1277162ef2df452d321951e989ce87dc9ced"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:e4fae13126f13a8d9420b74fb5a5ff6a6b2f91f7718c4be2d4a8dc1337c58f59"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:e352eebc23dc94fb79e67a056c057fb0e16c20c8cb881dc826094c20ed4791e3"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:b43f5c1f053a170e6e4b44ba69838ac223f9051adca1a56506d4c46e98d1485f"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:ed245fad8de6a134d5c3a630204e7f8238aa944a40388005bce0ce3718c410fa"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:22a9eefdbfe520778512266d0b48ff239eaa8d272fce6f5cb1ff352bed0619f4"}, + {file = "winrt_Windows.Devices.Enumeration-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:397d43f8fd2621a7719b9eab6a4a8e72a1d6fa2d9c36525a30812f8e7bad3bdf"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.ApplicationModel.Background[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Security.Credentials[all] (==2.0.0-beta.1)", "winrt-Windows.Storage.Streams[all] (==2.0.0-beta.1)", "winrt-Windows.UI.Popups[all] (==2.0.0-beta.1)", "winrt-Windows.UI[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-foundation" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Foundation-2.0.0b1.tar.gz", hash = "sha256:976b6da942747a7ca5a179a35729d8dc163f833e03b085cf940332a5e9070d54"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:5337ac1ec260132fbff868603e73a3738d4001911226e72669b3d69c8a256d5e"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:af969e5bb9e2e41e4e86a361802528eafb5eb8fe87ec1dba6048c0702d63caa8"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:bbbfa6b3c444a1074a630fd4a1b71171be7a5c9bb07c827ad9259fadaed56cf2"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:b91bd92b1854c073acd81aa87cf8df571d2151b1dd050b6181aa36f7acc43df4"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:2f5359f25703347e827dbac982150354069030f1deecd616f7ce37ad90cbcb00"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:0f1f1978173ddf0ee6262c2edb458f62d628b9fa0df10cd1e8c78c833af3197e"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:c1d23b737f733104b91c89c507b58d0b3ef5f3234a1b608ef6dfb6dbbb8777ea"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:95de6c29e9083fe63f127b965b54dfa52a6424a93a94ce87cfad4c1900a6e887"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:4707063a5a6980e3f71aebeea5ac93101c753ec13a0b47be9ea4dbc0d5ff361e"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:d0259f1f4a1b8e20d0cbd935a889c0f7234f720645590260f9cf3850fdc1e1fa"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:15c7b324d0f59839fb4492d84bb1c870881c5c67cb94ac24c664a7c4dce1c475"}, + {file = "winrt_Windows.Foundation-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:16ad741f4d38e99f8409ba5760299d0052003255f970f49f4b8ba2e0b609c8b7"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-foundation-collections" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Foundation.Collections-2.0.0b1.tar.gz", hash = "sha256:185d30f8103934124544a40aac005fa5918a9a7cb3179f45e9863bb86e22ad43"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:042142e916a170778b7154498aae61254a1a94c552954266b73479479d24f01d"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:9f68e66055121fc1e04c4fda627834aceee6fbe922e77d6ccaecf9582e714c57"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:a4609411263cc7f5e93a9a5677b21e2ef130e26f9030bfa960b3e82595324298"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:5296858aa44c53936460a119794b80eedd6bd094016c1bf96822f92cb95ea419"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:3db1e1c80c97474e7c88b6052bd8982ca61723fd58ace11dc91a5522662e0b2a"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:c3a594e660c59f9fab04ae2f40bda7c809e8ec4748bada4424dfb02b43d4bfe1"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:0f355ee943ec5b835e694d97e9e93545a42d6fb984a61f442467789550d62c3f"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:c4a0cd2eb9f47c7ca3b66d12341cc822250bf26854a93fd58ab77f7a48dfab3a"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:744dbef50e8b8f34904083cae9ad43ac6e28facb9e166c4f123ce8e758141067"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:b7c767184aec3a3d7cba2cd84fadcd68106854efabef1a61092052294d6d6f4f"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:7c1ffe99c12f14fc4ab7027757780e6d850fa2fb23ec404a54311fbd9f1970d3"}, + {file = "winrt_Windows.Foundation.Collections-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:870fa040ed36066e4c240c35973d8b2e0d7c38cc6050a42d993715ec9e3b748c"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Foundation[all] (==2.0.0-beta.1)"] + +[[package]] +name = "winrt-windows-storage-streams" +version = "2.0.0b1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "winrt-Windows.Storage.Streams-2.0.0b1.tar.gz", hash = "sha256:029d67cdc9b092d56c682740fe3c42f267dc5d3346b5c0b12ebc03f38e7d2f1f"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp310-cp310-win32.whl", hash = "sha256:49c90d4bfd539f6676226dfcb4b3574ddd6be528ffc44aa214c55af88c2de89e"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:22cc82779cada84aa2633841e25b33f3357737d912a1d9ecc1ee5a8b799b5171"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp310-cp310-win_arm64.whl", hash = "sha256:b1750a111be32466f4f0781cbb5df195ac940690571dff4564492b921b162563"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp311-cp311-win32.whl", hash = "sha256:e79b1183ab26d9b95cf3e6dbe3f488a40605174a5a112694dbb7dbfb50899daf"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp311-cp311-win_amd64.whl", hash = "sha256:3e90a1207eb3076f051a7785132f7b056b37343a68e9481a50c6defb3f660099"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp311-cp311-win_arm64.whl", hash = "sha256:4da06522b4fa9cfcc046b604cc4aa1c6a887cc4bb5b8a637ed9bff8028a860bb"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp312-cp312-win32.whl", hash = "sha256:6f74f8ab8ac0d8de61c709043315361d8ac63f8144f3098d428472baadf8246a"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp312-cp312-win_amd64.whl", hash = "sha256:5cf7c8d67836c60392d167bfe4f98ac7abcb691bfba2d19e322d0f9181f58347"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp312-cp312-win_arm64.whl", hash = "sha256:f7f679f2c0f71791eca835856f57942ee5245094c1840a6c34bc7c2176b1bcd6"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp39-cp39-win32.whl", hash = "sha256:5beb53429fa9a11ede56b4a7cefe28c774b352dd355f7951f2a4dd7e9ec9b39a"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:f84233c4b500279d8f5840cb8c47776bc040fcecba05c6c9ab9767053698fc8b"}, + {file = "winrt_Windows.Storage.Streams-2.0.0b1-cp39-cp39-win_arm64.whl", hash = "sha256:cfb163ddbb435906f75ef92a768573b0190e194e1438cea5a4c1d4d32a6b9386"}, +] + +[package.dependencies] +winrt-runtime = "2.0.0-beta.1" + +[package.extras] +all = ["winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Storage[all] (==2.0.0-beta.1)", "winrt-Windows.System[all] (==2.0.0-beta.1)"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "zipp" +version = "3.19.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[extras] +tunnel = [] + +[metadata] +lock-version = "2.0" +python-versions = "^3.9,<3.13" +content-hash = "c4f536f1ab171c8b59cbd0cbee4779b87f49348926f68f9f92bc22ff51134d7a" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e114a97 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,53 @@ +[tool.poetry] +name = "meshtastic" +version = "2.3.7" +description = "Python API & client shell for talking to Meshtastic devices" +authors = ["Meshtastic Developers "] +license = "GPL-3.0-only" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.9,<3.13" # was 3.7 for production but 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +pyserial = "^3.5" +protobuf = ">=5.26.0" +dotmap = "^1.3.30" +pexpect = "^4.9.0" +pyqrcode = "^1.2.1" +tabulate = "^0.9.0" +timeago = "^1.0.16" +webencodings = "^0.5.1" +requests = "^2.31.0" +pyparsing = "^3.1.2" +pyyaml = "^6.0.1" +pypubsub = "^4.0.3" +bleak = "^0.21.1" +mypy = "^1.10.0" +mypy-protobuf = "^3.6.0" +types-protobuf = "^5.26.0.20240422" +types-tabulate = "^0.9.0.20240106" +types-requests = "^2.31.0.20240406" +types-setuptools = "^69.5.0.20240423" +types-pyyaml = "^6.0.12.20240311" +packaging = "^24.0" + +[tool.poetry.group.dev.dependencies] +hypothesis = "^6.103.2" +pytest = "^8.2.2" +pytest-cov = "^5.0.0" +pdoc3 = "^0.10.0" +autopep8 = "^2.1.0" +riden = {git = "https://github.com/shaybox/riden.git"} +pandas = "^2.2.2" +pylint = "^2.11.1" +pytap2 = "^2.3.0" + +[tool.poetry.extras] +tunnel = ["pytap2"] + +[tool.poetry.scripts] +meshtastic = "meshtastic.__main__:main" +mesh-tunnel = "meshtastic.__main__:tunnelMain [tunnel]" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index fe49987..0000000 --- a/requirements.txt +++ /dev/null @@ -1,30 +0,0 @@ -markdown -pyserial -protobuf>=5.26.0 -dotmap -pexpect -pyqrcode -tabulate -timeago -webencodings -requests -pyparsing -twine -autopep8 -pylint -pytest -pytest-cov -hypothesis -pyyaml -pytap2 -pdoc3 -pypubsub -bleak -packaging -mypy -mypy-protobuf -types-protobuf>=5.26.0 -types-tabulate -types-requests -types-setuptools -types-PyYAML diff --git a/setup.py b/setup.py deleted file mode 100644 index 7aaacf9..0000000 --- a/setup.py +++ /dev/null @@ -1,56 +0,0 @@ -# Note: you shouldn't need to run this script manually. It is run implicitly by the pip3 install command. - -import pathlib - -from setuptools import setup - -# The directory containing this file -HERE = pathlib.Path(__file__).parent - -with open("README.md", "r") as fh: - long_description = fh.read() - -# This call to setup() does all the work -setup( - name="meshtastic", - version="2.3.11", - description="Python API & client shell for talking to Meshtastic devices", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/meshtastic/python", - author="Meshtastic Developers", - author_email="contact@meshtastic.org", - license="GPL-3.0-only", - classifiers=[ - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - "Development Status :: 4 - Beta", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - ], - packages=["meshtastic"], - include_package_data=True, - install_requires=[ - "pyserial>=3.4", - "protobuf>=5.26.0", - "requests>=2.25.0", - "pypubsub>=4.0.3", - "dotmap>=1.3.14", - "pyqrcode>=1.2.1", - "tabulate>=0.8.9", - "timeago>=1.0.15", - "pyyaml", - "bleak>=0.21.1", - "packaging", - ], - extras_require={"tunnel": ["pytap2>=2.0.0"]}, - python_requires=">=3.7", - entry_points={ - "console_scripts": [ - "meshtastic=meshtastic.__main__:main", - "mesh-tunnel=meshtastic.__main__:tunnelMain [tunnel]", - ] - }, -) From 9e319f3c525b9df0b5fd1baddb18eac0d0a06d01 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 22 Jun 2024 07:49:06 -0700 Subject: [PATCH 008/248] update CI scripts to allow running CI on the desktop (see below) * add script to run 'act' local github actions tool (lets devs check github actions on their local machine) * Update various github actions to latest (so they can work with the 'act' tool) * change a few places where python version was not properly quoted as a string (act yaml parser is more strict than the github version) * update pylint min-version to work with recent github actions * remove pandas/riden requirement (that's in my other branch for now) --- .github/workflows/ci.yml | 17 +- .github/workflows/release.yml | 24 +- .github/workflows/update_protobufs.yml | 2 +- .gitignore | 1 + bin/run-ci-local.sh | 6 + poetry.lock | 387 ++----------------------- pyproject.toml | 6 +- 7 files changed, 50 insertions(+), 393 deletions(-) create mode 100755 bin/run-ci-local.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36e6c7b..39f8992 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,23 +18,24 @@ jobs: - "3.10" - "3.11" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Python 3 - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 - name: Uninstall meshtastic run: | - pip3 uninstall meshtastic + pip3 uninstall -y meshtastic - name: Install dependencies run: | python -m pip install --upgrade pip pip3 install poetry - name: Install meshtastic from local run: | + poetry install poetry run meshtastic --version - name: Run pylint run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" - name: Check types with mypy - run: mypy meshtastic/ + run: poetry run mypy meshtastic/ - name: Run tests with pytest run: poetry run pytest --cov=meshtastic - name: Generate coverage report @@ -60,10 +61,12 @@ jobs: - "3.10" - "3.11" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Python 3 - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 - name: Install meshtastic from local run: | + python -m pip install --upgrade pip + pip3 install poetry poetry install - meshtastic --version + poetry run meshtastic --version diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6c0b19c..d0ed392 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Bump version run: >- @@ -48,9 +48,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python 3.9 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.9" - name: Install pypa/build run: >- @@ -79,14 +79,14 @@ jobs: # needs: release_create # steps: # - name: Checkout - # uses: actions/checkout@v3 + # uses: actions/checkout@v4 # with: # ref: ${{ needs.release_create.outputs.new_sha }} # - name: Set up Python 3.9 - # uses: actions/setup-python@v2 + # uses: actions/setup-python@v5 # with: - # python-version: 3.9 + # python-version: "3.9" # - name: Setup code signing # env: @@ -125,14 +125,14 @@ jobs: needs: release_create steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ needs.release_create.outputs.new_sha }} - name: Set up Python 3.9 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.9" - name: Build run: | @@ -166,14 +166,14 @@ jobs: needs: release_create steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ needs.release_create.outputs.new_sha }} - name: Set up Python 3.9 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.9" - name: Build run: | diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index d1a4cd6..86049b7 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -7,7 +7,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: true diff --git a/.gitignore b/.gitignore index 578ac95..d064e44 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ __pycache__ examples/__pycache__ meshtastic.spec .hypothesis/ +coverage.xml \ No newline at end of file diff --git a/bin/run-ci-local.sh b/bin/run-ci-local.sh new file mode 100755 index 0000000..69aa5ea --- /dev/null +++ b/bin/run-ci-local.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# This script lets you run github ci actions locally + +# also: we only run one of the 4 matrix tests, because otherwise it absolutely hammers the CPU (so many containers and threads) +act -P ubuntu-latest=-self-hosted --matrix "python-version:3.8" \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 187f251..9ef9b64 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,23 +1,18 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "astroid" -version = "2.15.8" +version = "3.2.2" description = "An abstract syntax tree for Python with inference support." optional = false -python-versions = ">=3.7.2" +python-versions = ">=3.8.0" files = [ - {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, - {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, + {file = "astroid-3.2.2-py3-none-any.whl", hash = "sha256:e8a0083b4bb28fcffb6207a3bfc9e5d0a68be951dd7e336d5dcf639c682388c0"}, + {file = "astroid-3.2.2.tar.gz", hash = "sha256:8ead48e31b92b2e217b6c9733a21afafe479d52d6e164dd25fb1a770c7c3cf94"}, ] [package.dependencies] -lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} -wrapt = [ - {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, - {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, -] [[package]] name = "async-timeout" @@ -221,20 +216,6 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -484,52 +465,6 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] -[[package]] -name = "lazy-object-proxy" -version = "1.10.0" -description = "A fast and thorough lazy object proxy." -optional = false -python-versions = ">=3.8" -files = [ - {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, - {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, -] - [[package]] name = "mako" version = "1.3.5" @@ -647,20 +582,6 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -[[package]] -name = "modbus-tk" -version = "1.1.3" -description = "Implementation of modbus protocol in python" -optional = false -python-versions = "*" -files = [ - {file = "modbus_tk-1.1.3-py3-none-any.whl", hash = "sha256:2b7afca05292a58371e7a7e4ec2931f2bb9b8a1a7c0295ada758740e72985aef"}, - {file = "modbus_tk-1.1.3.tar.gz", hash = "sha256:690fa7bb86ea978992465d2d61c8b5acc639ce0e8b833a0aa96d4dd172c5644a"}, -] - -[package.dependencies] -pyserial = ">=3.1" - [[package]] name = "mypy" version = "1.10.0" @@ -734,60 +655,6 @@ files = [ protobuf = ">=4.25.3" types-protobuf = ">=4.24" -[[package]] -name = "numpy" -version = "2.0.0" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "numpy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f"}, - {file = "numpy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2"}, - {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238"}, - {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514"}, - {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196"}, - {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1"}, - {file = "numpy-2.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc"}, - {file = "numpy-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787"}, - {file = "numpy-2.0.0-cp310-cp310-win32.whl", hash = "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98"}, - {file = "numpy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b"}, - {file = "numpy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5"}, - {file = "numpy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289"}, - {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609"}, - {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871"}, - {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4"}, - {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581"}, - {file = "numpy-2.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995"}, - {file = "numpy-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f"}, - {file = "numpy-2.0.0-cp311-cp311-win32.whl", hash = "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f"}, - {file = "numpy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c"}, - {file = "numpy-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f"}, - {file = "numpy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85"}, - {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2"}, - {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e"}, - {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2"}, - {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a"}, - {file = "numpy-2.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95"}, - {file = "numpy-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"}, - {file = "numpy-2.0.0-cp312-cp312-win32.whl", hash = "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54"}, - {file = "numpy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df"}, - {file = "numpy-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de"}, - {file = "numpy-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb"}, - {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f"}, - {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86"}, - {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a"}, - {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d"}, - {file = "numpy-2.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4"}, - {file = "numpy-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44"}, - {file = "numpy-2.0.0-cp39-cp39-win32.whl", hash = "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275"}, - {file = "numpy-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65"}, - {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6"}, - {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a"}, - {file = "numpy-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad"}, - {file = "numpy-2.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9"}, - {file = "numpy-2.0.0.tar.gz", hash = "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864"}, -] - [[package]] name = "packaging" version = "24.1" @@ -799,79 +666,6 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] -[[package]] -name = "pandas" -version = "2.2.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, - {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, - {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, - {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, - {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, - {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, - {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - [[package]] name = "pdoc3" version = "0.10.0" @@ -976,23 +770,24 @@ files = [ [[package]] name = "pylint" -version = "2.17.7" +version = "3.2.3" description = "python code static checker" optional = false -python-versions = ">=3.7.2" +python-versions = ">=3.8.0" files = [ - {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, - {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, + {file = "pylint-3.2.3-py3-none-any.whl", hash = "sha256:b3d7d2708a3e04b4679e02d99e72329a8b7ee8afb8d04110682278781f889fa8"}, + {file = "pylint-3.2.3.tar.gz", hash = "sha256:02f6c562b215582386068d52a30f520d84fdbcf2a95fc7e855b816060d048b60"}, ] [package.dependencies] -astroid = ">=2.15.8,<=2.17.0-dev0" +astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] -isort = ">=4.2.5,<6" +isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -1180,31 +975,6 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -1285,37 +1055,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "riden" -version = "1.2.0" -description = "A python library for Riden RD power supplies" -optional = false -python-versions = ">=3.7,<4.0" -files = [] -develop = false - -[package.dependencies] -click = "^8.0.3" -modbus_tk = "^1.1.2" -pyserial = "^3.5" - -[package.source] -type = "git" -url = "https://github.com/shaybox/riden.git" -reference = "HEAD" -resolved_reference = "ecbda543cf566346dd28558d957b4aa7fe116a83" - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1397,13 +1136,13 @@ files = [ [[package]] name = "types-requests" -version = "2.32.0.20240602" +version = "2.32.0.20240622" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.32.0.20240602.tar.gz", hash = "sha256:3f98d7bbd0dd94ebd10ff43a7fbe20c3b8528acace6d8efafef0b6a184793f06"}, - {file = "types_requests-2.32.0.20240602-py3-none-any.whl", hash = "sha256:ed3946063ea9fbc6b5fc0c44fa279188bae42d582cb63760be6cb4b9d06c3de8"}, + {file = "types-requests-2.32.0.20240622.tar.gz", hash = "sha256:ed5e8a412fcc39159d6319385c009d642845f250c63902718f605cd90faade31"}, + {file = "types_requests-2.32.0.20240622-py3-none-any.whl", hash = "sha256:97bac6b54b5bd4cf91d407e62f0932a74821bc2211f22116d9ee1dd643826caf"}, ] [package.dependencies] @@ -1442,17 +1181,6 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -[[package]] -name = "tzdata" -version = "2024.1" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, -] - [[package]] name = "urllib3" version = "2.2.2" @@ -1699,85 +1427,6 @@ winrt-runtime = "2.0.0-beta.1" [package.extras] all = ["winrt-Windows.Foundation.Collections[all] (==2.0.0-beta.1)", "winrt-Windows.Foundation[all] (==2.0.0-beta.1)", "winrt-Windows.Storage[all] (==2.0.0-beta.1)", "winrt-Windows.System[all] (==2.0.0-beta.1)"] -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - [[package]] name = "zipp" version = "3.19.2" @@ -1798,5 +1447,5 @@ tunnel = [] [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.13" -content-hash = "c4f536f1ab171c8b59cbd0cbee4779b87f49348926f68f9f92bc22ff51134d7a" +python-versions = "^3.8,<3.13" +content-hash = "372f4891aa67c5e358a8e3122f332ec17f0f36143dfcd314acf4de5b26f2a888" diff --git a/pyproject.toml b/pyproject.toml index e114a97..c49d8be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" readme = "README.md" [tool.poetry.dependencies] -python = "^3.9,<3.13" # was 3.7 for production but 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +python = "^3.8,<3.13" # was 3.7 for production but, 3.8 is needed for pytap2, 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason pyserial = "^3.5" protobuf = ">=5.26.0" dotmap = "^1.3.30" @@ -36,9 +36,7 @@ pytest = "^8.2.2" pytest-cov = "^5.0.0" pdoc3 = "^0.10.0" autopep8 = "^2.1.0" -riden = {git = "https://github.com/shaybox/riden.git"} -pandas = "^2.2.2" -pylint = "^2.11.1" +pylint = "^3.2.3" pytap2 = "^2.3.0" [tool.poetry.extras] From 4203553a44b2298874329cef0e1d1eeaf8c3cda9 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 22 Jun 2024 08:32:42 -0700 Subject: [PATCH 009/248] changes to (hopefully) make release CI actions work add pyinstaller as a dev dep. Use it to make "bin/build-bin.sh" remove old version scripts (no longer needed with poetry) --- .github/workflows/release.yml | 49 ++++++--------- bin/build-bin.sh | 9 +++ bin/bump_version.py | 30 --------- bin/run-ci-local.sh | 7 ++- bin/show_version.py | 20 ------ poetry.lock | 115 +++++++++++++++++++++++++++++++++- pyproject.toml | 3 +- 7 files changed, 150 insertions(+), 83 deletions(-) create mode 100755 bin/build-bin.sh delete mode 100755 bin/bump_version.py delete mode 100755 bin/show_version.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d0ed392..9fb71c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,24 +14,34 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip3 install poetry + - name: Bump version run: >- - bin/bump_version.py + poetry version patch - - name: Commit updated version.py + - name: Commit updated version. id: commit_updated run: | git config --global user.name 'github-actions' git config --global user.email 'bot@noreply.github.com' git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git add setup.py + git add pyproject.toml git commit -m "bump version" && git push || echo "No changes to commit" git log -n 1 --pretty=format:"%H" | tail -n 1 | awk '{print "::set-output name=sha::"$0}' - name: Get version id: get_version run: >- - bin/show_version.py + poetry version - name: Create GitHub release uses: actions/create-release@v1 @@ -47,26 +57,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install pypa/build - run: >- - python -m - pip install - build - --user - - name: Build a binary wheel and a source tarball run: >- - python -m - build - --sdist - --wheel - --outdir dist/ - . + poetry build - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@master @@ -136,10 +129,8 @@ jobs: - name: Build run: | - pip install pyinstaller - pip install -r requirements.txt - pip install . - pyinstaller -F -n meshtastic --collect-all meshtastic meshtastic/__main__.py + pip install poetry + bin/build-bin.sh - name: Add ubuntu to release uses: actions/upload-release-asset@v1 @@ -177,10 +168,8 @@ jobs: - name: Build run: | - pip install pyinstaller - pip install -r requirements.txt - pip install . - pyinstaller -F -n meshtastic --collect-all meshtastic meshtastic/__main__.py + pip install poetry + bin/build-bin.sh - name: Add windows to release uses: actions/upload-release-asset@v1 diff --git a/bin/build-bin.sh b/bin/build-bin.sh new file mode 100755 index 0000000..d85beb7 --- /dev/null +++ b/bin/build-bin.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +echo Building ubuntu binary +poetry install +source $(poetry env info --path)/bin/activate +pyinstaller -F -n meshtastic --collect-all meshtastic meshtastic/__main__.py + diff --git a/bin/bump_version.py b/bin/bump_version.py deleted file mode 100755 index 7279cdf..0000000 --- a/bin/bump_version.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -"""Bump the version number""" -import re - -version_filename = "setup.py" - -lines = None - -with open(version_filename, "r", encoding="utf-8") as f: - lines = f.readlines() - -with open(version_filename, "w", encoding="utf-8") as f: - for line in lines: - if line.lstrip().startswith("version="): - # get rid of quotes around the version - line = line.replace('"', "") - # get rid of trailing comma - line = line.replace(",", "") - # split on '=' - words = line.split("=") - # split the version into parts (by period) - v = words[1].split(".") - build_num = re.findall(r"\d+", v[2])[0] - new_build_num = str(int(build_num) + 1) - ver = f"{v[0]}.{v[1]}.{v[2].replace(build_num, new_build_num)}".replace( - "\n", "" - ) - f.write(f' version="{ver}",\n') - else: - f.write(line) diff --git a/bin/run-ci-local.sh b/bin/run-ci-local.sh index 69aa5ea..a446d0d 100755 --- a/bin/run-ci-local.sh +++ b/bin/run-ci-local.sh @@ -1,6 +1,11 @@ #!/bin/bash # This script lets you run github ci actions locally +# You need to have act installed. You can get it at https://nektosact.com/ + +# by default it simulates a push event +# other useful options +# -j build-and-publish-ubuntu # also: we only run one of the 4 matrix tests, because otherwise it absolutely hammers the CPU (so many containers and threads) -act -P ubuntu-latest=-self-hosted --matrix "python-version:3.8" \ No newline at end of file +act -P ubuntu-latest=-self-hosted --matrix "python-version:3.8" "$@" \ No newline at end of file diff --git a/bin/show_version.py b/bin/show_version.py deleted file mode 100755 index 8cfb092..0000000 --- a/bin/show_version.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python -"""Show the version number""" - -version_filename = "setup.py" - -lines = None - -with open(version_filename, "r", encoding="utf-8") as f: - lines = f.readlines() - -for line in lines: - if line.lstrip().startswith("version="): - # get rid of quotes around the version - line2 = line.replace('"', "") - # get rid of the trailing comma - line2 = line2.replace(",", "") - # split on = - words = line2.split("=") - # Note: This format is for github actions - print(f"::set-output name=version::{words[1].strip()}") diff --git a/poetry.lock b/poetry.lock index 9ef9b64..e7286ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +[[package]] +name = "altgraph" +version = "0.17.4" +description = "Python graph (network) package" +optional = false +python-versions = "*" +files = [ + {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, + {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, +] + [[package]] name = "astroid" version = "3.2.2" @@ -465,6 +476,20 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "macholib" +version = "1.16.3" +description = "Mach-O header analysis and editing" +optional = false +python-versions = "*" +files = [ + {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, + {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, +] + +[package.dependencies] +altgraph = ">=0.17" + [[package]] name = "mako" version = "1.3.5" @@ -681,6 +706,17 @@ files = [ mako = "*" markdown = ">=3.0" +[[package]] +name = "pefile" +version = "2023.2.7" +description = "Python PE parsing module" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"}, + {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"}, +] + [[package]] name = "pexpect" version = "4.9.0" @@ -768,6 +804,57 @@ files = [ {file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"}, ] +[[package]] +name = "pyinstaller" +version = "6.8.0" +description = "PyInstaller bundles a Python application and all its dependencies into a single package." +optional = false +python-versions = "<3.13,>=3.8" +files = [ + {file = "pyinstaller-6.8.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ff6bc2784c1026f8e2f04aa3760cbed41408e108a9d4cf1dd52ee8351a3f6e1"}, + {file = "pyinstaller-6.8.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:39ac424d2ee2457d2ab11a5091436e75a0cccae207d460d180aa1fcbbafdd528"}, + {file = "pyinstaller-6.8.0-py3-none-manylinux2014_i686.whl", hash = "sha256:355832a3acc7de90a255ecacd4b9f9e166a547a79c8905d49f14e3a75c1acdb9"}, + {file = "pyinstaller-6.8.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:6303c7a009f47e6a96ef65aed49f41e36ece8d079b9193ca92fe807403e5fe80"}, + {file = "pyinstaller-6.8.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2b71509468c811968c0b5decb5bbe85b6292ea52d7b1f26313d2aabb673fa9a5"}, + {file = "pyinstaller-6.8.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ff31c5b99e05a4384bbe2071df67ec8b2b347640a375eae9b40218be2f1754c6"}, + {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:000c36b13fe4cd8d0d8c2bc855b1ddcf39867b5adf389e6b5ca45b25fa3e619d"}, + {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:fe0af018d7d5077180e3144ada89a4da5df8d07716eb7e9482834a56dc57a4e8"}, + {file = "pyinstaller-6.8.0-py3-none-win32.whl", hash = "sha256:d257f6645c7334cbd66f38a4fac62c3ad614cc46302b2b5d9f8cc48c563bce0e"}, + {file = "pyinstaller-6.8.0-py3-none-win_amd64.whl", hash = "sha256:81cccfa9b16699b457f4788c5cc119b50f3cd4d0db924955f15c33f2ad27a50d"}, + {file = "pyinstaller-6.8.0-py3-none-win_arm64.whl", hash = "sha256:1c3060a263758cf7f0144ab4c016097b20451b2469d468763414665db1bb743d"}, + {file = "pyinstaller-6.8.0.tar.gz", hash = "sha256:3f4b6520f4423fe19bcc2fd63ab7238851ae2bdcbc98f25bc5d2f97cc62012e9"}, +] + +[package.dependencies] +altgraph = "*" +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} +packaging = ">=22.0" +pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} +pyinstaller-hooks-contrib = ">=2024.6" +pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} +setuptools = ">=42.0.0" + +[package.extras] +completion = ["argcomplete"] +hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] + +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2024.7" +description = "Community maintained hooks for PyInstaller" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyinstaller_hooks_contrib-2024.7-py2.py3-none-any.whl", hash = "sha256:8bf0775771fbaf96bcd2f4dfd6f7ae6c1dd1b1efe254c7e50477b3c08e7841d8"}, + {file = "pyinstaller_hooks_contrib-2024.7.tar.gz", hash = "sha256:fd5f37dcf99bece184e40642af88be16a9b89613ecb958a8bd1136634fc9fac5"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +packaging = ">=22.0" +setuptools = ">=42.0.0" + [[package]] name = "pylint" version = "3.2.3" @@ -975,6 +1062,17 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "pywin32-ctypes" +version = "0.2.2" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, + {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, +] + [[package]] name = "pyyaml" version = "6.0.1" @@ -1055,6 +1153,21 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "setuptools" +version = "70.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, + {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1448,4 +1561,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.13" -content-hash = "372f4891aa67c5e358a8e3122f332ec17f0f36143dfcd314acf4de5b26f2a888" +content-hash = "2ee78b53bdbdb0d560d2092d28d4379ec0ca18377e9d698f152d708318f9ca23" diff --git a/pyproject.toml b/pyproject.toml index c49d8be..94cbcd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.7" +version = "2.3.11" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" @@ -38,6 +38,7 @@ pdoc3 = "^0.10.0" autopep8 = "^2.1.0" pylint = "^3.2.3" pytap2 = "^2.3.0" +pyinstaller = "^6.8.0" [tool.poetry.extras] tunnel = ["pytap2"] From b41cb7d8dfeee9f5a9e7ebad3a37dd6722f2ba3f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 10:34:16 -0700 Subject: [PATCH 010/248] Merge branch 'pr-poetry' into powermon --- .vscode/launch.json | 12 +- meshtastic/__main__.py | 16 +++ meshtastic/mesh_interface.py | 9 +- meshtastic/observable.py | 35 +++++ meshtastic/power_mon.py | 143 +++++++++++++++++++++ meshtastic/powermon_pb2.py | 28 ++++ meshtastic/powermon_pb2.pyi | 84 ++++++++++++ meshtastic/stream_interface.py | 29 ++++- poetry.lock | 226 ++++++++++++++++++++++++++++++++- protobufs | 2 +- pyproject.toml | 4 +- 11 files changed, 575 insertions(+), 13 deletions(-) create mode 100644 meshtastic/observable.py create mode 100644 meshtastic/power_mon.py create mode 100644 meshtastic/powermon_pb2.py create mode 100644 meshtastic/powermon_pb2.pyi diff --git a/.vscode/launch.json b/.vscode/launch.json index aca86dd..b093786 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -106,7 +106,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": true, - "args": ["--debug", "--set", "power.is_power_saving", "1"] + "args": ["--set", "power.powermon_enables", "65527"] }, { "name": "meshtastic debug setPref telemetry.environment_measurement_enabled", @@ -164,7 +164,15 @@ "request": "launch", "module": "meshtastic", "justMyCode": true, - "args": ["--debug", "--seriallog", "stdout"] + "args": ["--noproto", "--seriallog", "stdout"] + }, + { + "name": "meshtastic powermon", + "type": "python", + "request": "launch", + "module": "meshtastic", + "justMyCode": false, + "args": ["--power-mon", "/dev/ttyUSB1", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fa71adc..3db80ba 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -21,6 +21,7 @@ from meshtastic import channel_pb2, config_pb2, portnums_pb2, remote_hardware, B from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface +from meshtastic.power_mon import PowerMonClient def onReceive(packet, interface): """Callback invoked when a packet arrives""" @@ -1089,6 +1090,10 @@ def common(): # We assume client is fully connected now onConnected(client) + if args.power_mon: + PowerMonClient(args.power_mon, client) + + have_tunnel = platform.system() == "Linux" if ( args.noproto or args.reply or (have_tunnel and args.tunnel) or args.listen @@ -1500,6 +1505,17 @@ def initParser(): action="store_true", ) + group.add_argument( + "--power-mon", + help="Capture any power monitor records. You must use --power-mon /dev/ttyUSBxxx to specify which port the power supply is on", + ) + + group.add_argument( + "--power-stress", + help="Perform power monitor stress testing, to capture a power consumption profile for the device (also requires --power-mon)", + action="store_true", + ) + group.add_argument( "--ble-scan", help="Scan for Meshtastic BLE devices", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 5b3403c..0bc67ba 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -29,7 +29,7 @@ from meshtastic import ( NODELESS_WANT_CONFIG_ID, ResponseHandler, protocols, - publishingThread, + publishingThread ) from meshtastic.util import ( Acknowledgment, @@ -40,7 +40,7 @@ from meshtastic.util import ( stripnl, message_to_json, ) - +from meshtastic.observable import Observable class MeshInterface: # pylint: disable=R0902 """Interface class for meshtastic devices @@ -71,6 +71,7 @@ class MeshInterface: # pylint: disable=R0902 self.nodes: Optional[Dict[str,Dict]] = None # FIXME self.isConnected: threading.Event = threading.Event() self.noProto: bool = noProto + self.onLogMessage = Observable() self.localNode: meshtastic.node.Node = meshtastic.node.Node(self, -1) # We fixup nodenum later self.myInfo: Optional[mesh_pb2.MyNodeInfo] = None # We don't have device info yet self.metadata: Optional[mesh_pb2.DeviceMetadata] = None # We don't have device metadata yet @@ -111,6 +112,10 @@ class MeshInterface: # pylint: disable=R0902 logging.error(f"Traceback: {traceback}") self.close() + def _handleLogLine(self, line): + """Handle a line of log output from the device.""" + self.onLogMessage.fire(message=line) + def showInfo(self, file=sys.stdout) -> str: # pylint: disable=W0613 """Show human readable summary about this object""" owner = f"Owner: {self.getLongName()} ({self.getShortName()})" diff --git a/meshtastic/observable.py b/meshtastic/observable.py new file mode 100644 index 0000000..2bd2a5b --- /dev/null +++ b/meshtastic/observable.py @@ -0,0 +1,35 @@ + + +class Event(object): + """A simple event class.""" + +class Observable(object): + """A class that represents an observable object. + + To publish an event call fire(type="progress", percent=50) or whatever. It will call + """ + + def __init__(self): + """Initialize the Observable object.""" + self.callbacks = [] + + def subscribe(self, callback): + """Subscribe to the observable object. + + Args: + callback (function): The callback function to be called when the event is fired. + """ + self.callbacks.append(callback) + + def fire(self, **attrs): + """Fire the event. + + Args: + **attrs: Arbitrary keyword arguments to be passed to the callback functions. + """ + e = Event() + e.source = self + for k, v in attrs.items(): + setattr(e, k, v) + for fn in self.callbacks: + fn(e) \ No newline at end of file diff --git a/meshtastic/power_mon.py b/meshtastic/power_mon.py new file mode 100644 index 0000000..377ba33 --- /dev/null +++ b/meshtastic/power_mon.py @@ -0,0 +1,143 @@ +"""code logging power consumption of meshtastic devices.""" + +import logging +import re +import atexit +from datetime import datetime + +import pandas as pd +from riden import Riden + +from meshtastic.mesh_interface import MeshInterface +from meshtastic.observable import Event + + +class PowerSupply: + """Interface for talking to programmable bench-top power supplies. + Currently only the Riden supplies are supported (RD6006 tested) + """ + + def __init__(self, portName: str = "/dev/ttyUSB0"): + """Initialize the PowerSupply object.""" + self.r = r = Riden(port=portName, baudrate=115200, address=1) + logging.info( + f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." + ) + r.set_date_time(datetime.now()) + + def powerOn(self): + """Power on the supply, with reasonable defaults for meshtastic devices.""" + self.r.set_i_set( + 0.300 + ) # Set current limit to 300mA - hopefully enough to power any board but not break things if there is a short circuit + + # self.r.set_v_set(3.7) # default to a nominal LiPo voltage + self.r.set_v_set(3.3) # my WM1110 devboard header is directly connected to the 3.3V rail + self.r.set_output(1) + + """Get current watts out. + But for most applications you probably want getWattHour() instead (to prevent integration errors from accumulating). + """ + return self.r.get_p_out() + + def getWattHour(self): + """Get current Wh out, since power was turned on.""" + # FIXME: Individual reads seem busted in the riden lib. So for now I just read everything. + self.r.update() + return self.r.wh + # return self.r.get_wh() + + def clearWattHour(self): + """Clear the watt-hour counter FIXME.""" + + +"""Used to match power mon log lines: +INFO | ??:??:?? 7 [Blink] S:PM:0x00000080,reason +""" +logRegex = re.compile(".*S:PM:0x([0-9A-Fa-f]+),(.*)") + + +class PowerMonClient: + """Client for monitoring power consumption of meshtastic devices.""" + + def __init__(self, portName: str, client: MeshInterface) -> None: + """Initialize the PowerMonClient object. + + Args: + client (MeshInterface): The MeshInterface object to monitor. + + """ + self.client = client + self.state = 0 # The current power mon state bitfields + self.columns = ["time", "power", "reason", "bitmask"] + self.rawData = pd.DataFrame(columns=self.columns) # use time as the index + + # for efficiency reasons we keep new data in a list - only adding to rawData when needfed + self.newData = [] + + self.power = power = PowerSupply(portName) + power.powerOn() + + # Used to calculate watts over an interval + self.prevPowerTime = datetime.now() + self.prevWattHour = power.getWattHour() + atexit.register(self._exitHandler) + client.onLogMessage.subscribe(self._onLogMessage) + + def getRawData(self) -> pd.DataFrame: + """Get the raw data. + + Returns: + pd.DataFrame: The raw data. + + """ + df = pd.DataFrame(self.newData, columns=self.columns) + self.rawData = pd.concat([self.rawData, df], ignore_index=True) + self.newData = [] + + return self.rawData + + def _exitHandler(self) -> None: + """Exit handler.""" + fn = "/tmp/powermon.csv" # Find a better place + logging.info(f"Storing PowerMon raw data in {fn}") + self.getRawData().to_csv(fn) + + def _onLogMessage(self, ev: Event) -> None: + """Callback function for handling log messages. + + Args: + message (str): The log message. + + """ + m = logRegex.match(ev.message) + if m: + mask = int(m.group(1), 16) + reason = m.group(2) + logging.debug(f"PowerMon state: 0x{mask:x}, reason: {reason}") + if mask != self.state: + self._storeRecord(mask, reason) + + def _storeRecord(self, mask: int, reason: str) -> None: + """Store a power mon record. + + Args: + mask (int): The power mon state bitfields. + reason (str): The reason for the power mon state change. + + """ + + now = datetime.now() + nowWattHour = self.power.getWattHour() + watts = ( + (nowWattHour - self.prevWattHour) + / (now - self.prevPowerTime).total_seconds() + * 3600 + ) + self.prevPowerTime = now + self.prevWattHour = nowWattHour + self.state = mask + + self.newData.append( + {"time": now, "power": watts, "reason": reason, "bitmask": mask}) + # self.getRawData() diff --git a/meshtastic/powermon_pb2.py b/meshtastic/powermon_pb2.py new file mode 100644 index 0000000..bd91da4 --- /dev/null +++ b/meshtastic/powermon_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/powermon.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\x19meshtastic/powermon.proto\x12\x13meshtastic.PowerMon\"\'\n\x05\x45vent\x12\x13\n\x06states\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_states*\xfb\x01\n\x05State\x12\x08\n\x04None\x10\x00\x12\x11\n\rCPU_DeepSleep\x10\x01\x12\r\n\tCPU_Sleep\x10\x02\x12\r\n\tCPU_Awake\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\x11\n\x0cGPS_LowPower\x10\x80\x10\x12\x14\n\x0fGPS_MediumPower\x10\x80 \x12\x12\n\rGPS_HighPower\x10\x80@Bc\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.powermon_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016PowerMonProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_STATE']._serialized_start=92 + _globals['_STATE']._serialized_end=343 + _globals['_EVENT']._serialized_start=50 + _globals['_EVENT']._serialized_end=89 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/powermon_pb2.pyi b/meshtastic/powermon_pb2.pyi new file mode 100644 index 0000000..df6971a --- /dev/null +++ b/meshtastic/powermon_pb2.pyi @@ -0,0 +1,84 @@ +""" +@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 _State: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_State.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CPU_DeepSleep: _State.ValueType # 1 + CPU_Sleep: _State.ValueType # 2 + CPU_Awake: _State.ValueType # 4 + Lora_RXOn: _State.ValueType # 8 + Lora_TXOn: _State.ValueType # 16 + Lora_RXActive: _State.ValueType # 32 + BT_On: _State.ValueType # 64 + LED_On: _State.ValueType # 128 + Screen_On: _State.ValueType # 256 + Screen_Drawing: _State.ValueType # 512 + Wifi_On: _State.ValueType # 1024 + GPS_LowPower: _State.ValueType # 2048 + GPS_MediumPower: _State.ValueType # 4096 + GPS_HighPower: _State.ValueType # 8192 + +class State(_State, metaclass=_StateEnumTypeWrapper): + """Any significant power changing event in meshtastic should be tagged with a powermon state transition. + If you are making new meshtastic features feel free to add new entries at the end of this definition. + """ + +CPU_DeepSleep: State.ValueType # 1 +CPU_Sleep: State.ValueType # 2 +CPU_Awake: State.ValueType # 4 +Lora_RXOn: State.ValueType # 8 +Lora_TXOn: State.ValueType # 16 +Lora_RXActive: State.ValueType # 32 +BT_On: State.ValueType # 64 +LED_On: State.ValueType # 128 +Screen_On: State.ValueType # 256 +Screen_Drawing: State.ValueType # 512 +Wifi_On: State.ValueType # 1024 +GPS_LowPower: State.ValueType # 2048 +GPS_MediumPower: State.ValueType # 4096 +GPS_HighPower: State.ValueType # 8192 +global___State = State + +@typing.final +class Event(google.protobuf.message.Message): + """ + the log messages will be short and complete (see PowerMon.Event in the protobufs for details). + something like "PwrMon,C,0x00001234,REASON" where the hex number is the bitmask of all current states. + (We use a bitmask for states so that if a log message gets lost it won't be fatal) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STATES_FIELD_NUMBER: builtins.int + states: builtins.int + """Bitwise-OR of States""" + def __init__( + self, + *, + states: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_states", b"_states", "states", b"states"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_states", b"_states", "states", b"states"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_states", b"_states"]) -> typing.Literal["states"] | None: ... + +global___Event = Event diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index dea6923..c05a318 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -39,6 +39,7 @@ class StreamInterface(MeshInterface): self._wantExit = False self.is_windows11 = is_windows11() + self.cur_log_line = "" # FIXME, figure out why daemon=True causes reader thread to exit too early self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True) @@ -124,6 +125,26 @@ class StreamInterface(MeshInterface): if self._rxThread != threading.current_thread(): self._rxThread.join() # wait for it to exit + def _handleLogByte(self, b): + """Handle a byte that is part of a log message from the device.""" + + utf = "?" # assume we might fail + try: + utf = b.decode("utf-8") + except: + pass + + if utf == "\r": + pass # ignore + elif utf == "\n": + self._handleLogLine(self.cur_log_line) + self.cur_log_line = "" + else: + self.cur_log_line += utf + + if self.debugOut is not None: + self.debugOut.write(utf) + def __reader(self): """The reader thread that reads bytes from our stream""" logging.debug("in __reader()") @@ -146,11 +167,9 @@ class StreamInterface(MeshInterface): if ptr == 0: # looking for START1 if c != START1: self._rxBuf = empty # failed to find start - if self.debugOut is not None: - try: - self.debugOut.write(b.decode("utf-8")) - except: - self.debugOut.write("?") + # This must be a log message from the device + + self._handleLogByte(b) elif ptr == 1: # looking for START2 if c != START2: diff --git a/poetry.lock b/poetry.lock index e7286ba..a045de4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -227,6 +227,20 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -607,6 +621,20 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "modbus-tk" +version = "1.1.3" +description = "Implementation of modbus protocol in python" +optional = false +python-versions = "*" +files = [ + {file = "modbus_tk-1.1.3-py3-none-any.whl", hash = "sha256:2b7afca05292a58371e7a7e4ec2931f2bb9b8a1a7c0295ada758740e72985aef"}, + {file = "modbus_tk-1.1.3.tar.gz", hash = "sha256:690fa7bb86ea978992465d2d61c8b5acc639ce0e8b833a0aa96d4dd172c5644a"}, +] + +[package.dependencies] +pyserial = ">=3.1" + [[package]] name = "mypy" version = "1.10.0" @@ -680,6 +708,60 @@ files = [ protobuf = ">=4.25.3" types-protobuf = ">=4.24" +[[package]] +name = "numpy" +version = "2.0.0" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787"}, + {file = "numpy-2.0.0-cp310-cp310-win32.whl", hash = "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98"}, + {file = "numpy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f"}, + {file = "numpy-2.0.0-cp311-cp311-win32.whl", hash = "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f"}, + {file = "numpy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"}, + {file = "numpy-2.0.0-cp312-cp312-win32.whl", hash = "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54"}, + {file = "numpy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44"}, + {file = "numpy-2.0.0-cp39-cp39-win32.whl", hash = "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275"}, + {file = "numpy-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9"}, + {file = "numpy-2.0.0.tar.gz", hash = "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864"}, +] + [[package]] name = "packaging" version = "24.1" @@ -691,6 +773,79 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pdoc3" version = "0.10.0" @@ -1062,6 +1217,31 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + [[package]] name = "pywin32-ctypes" version = "0.2.2" @@ -1153,6 +1333,26 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "riden" +version = "1.2.0" +description = "A python library for Riden RD power supplies" +optional = false +python-versions = ">=3.7,<4.0" +files = [] +develop = false + +[package.dependencies] +click = "^8.0.3" +modbus_tk = "^1.1.2" +pyserial = "^3.5" + +[package.source] +type = "git" +url = "https://github.com/geeksville/riden.git#ecbda543cf566346dd28558d957b4aa7fe116a83" +reference = "HEAD" +resolved_reference = "ecbda543cf566346dd28558d957b4aa7fe116a83" + [[package]] name = "setuptools" version = "70.1.0" @@ -1168,6 +1368,17 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1294,6 +1505,17 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -1560,5 +1782,5 @@ tunnel = [] [metadata] lock-version = "2.0" -python-versions = "^3.8,<3.13" -content-hash = "2ee78b53bdbdb0d560d2092d28d4379ec0ca18377e9d698f152d708318f9ca23" +python-versions = "^3.9,<3.13" +content-hash = "b893063a1dfe925f901dc45b01d68e255e2bd0ba68bda54de83c875c17b964d8" diff --git a/protobufs b/protobufs index a641c5c..bfde27a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a641c5ce4fca158d18ca3cffc92ac7a10f9b6a04 +Subproject commit bfde27a4ea5cfd0f60ffe961b5ce249aaf54c182 diff --git a/pyproject.toml b/pyproject.toml index 94cbcd2..b2dc9a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" readme = "README.md" [tool.poetry.dependencies] -python = "^3.8,<3.13" # was 3.7 for production but, 3.8 is needed for pytap2, 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +python = "^3.9,<3.13" # was 3.7 for production but, 3.8 is needed for pytap2, 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason pyserial = "^3.5" protobuf = ">=5.26.0" dotmap = "^1.3.30" @@ -29,6 +29,8 @@ types-requests = "^2.31.0.20240406" types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" packaging = "^24.0" +riden = {git = "https://github.com/geeksville/riden.git#ecbda543cf566346dd28558d957b4aa7fe116a83"} +pandas = "^2.2.2" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From 725de4c2f94a23385171468edbd54621d1a34b06 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 16:43:56 -0700 Subject: [PATCH 011/248] move mypy and type info into dev-time only dependencies thx @njh --- poetry.lock | 108 ++++++++++++++++++++++++------------------------- pyproject.toml | 14 +++---- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/poetry.lock b/poetry.lock index e7286ba..0e4c244 100644 --- a/poetry.lock +++ b/poetry.lock @@ -240,63 +240,63 @@ files = [ [[package]] name = "coverage" -version = "7.5.3" +version = "7.5.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, - {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, - {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, - {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, - {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, - {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, - {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, - {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, - {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, - {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, - {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, - {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, - {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, - {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.dependencies] @@ -1561,4 +1561,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.13" -content-hash = "2ee78b53bdbdb0d560d2092d28d4379ec0ca18377e9d698f152d708318f9ca23" +content-hash = "ad7784653845f37d34feab43aa3947b8d6e51d7f4e51679a8730e26b98dbe453" diff --git a/pyproject.toml b/pyproject.toml index 94cbcd2..1ce1e4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,13 +21,6 @@ pyparsing = "^3.1.2" pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" -mypy = "^1.10.0" -mypy-protobuf = "^3.6.0" -types-protobuf = "^5.26.0.20240422" -types-tabulate = "^0.9.0.20240106" -types-requests = "^2.31.0.20240406" -types-setuptools = "^69.5.0.20240423" -types-pyyaml = "^6.0.12.20240311" packaging = "^24.0" [tool.poetry.group.dev.dependencies] @@ -39,6 +32,13 @@ autopep8 = "^2.1.0" pylint = "^3.2.3" pytap2 = "^2.3.0" pyinstaller = "^6.8.0" +mypy = "^1.10.0" +mypy-protobuf = "^3.6.0" +types-protobuf = "^5.26.0.20240422" +types-tabulate = "^0.9.0.20240106" +types-requests = "^2.31.0.20240406" +types-setuptools = "^69.5.0.20240423" +types-pyyaml = "^6.0.12.20240311" [tool.poetry.extras] tunnel = ["pytap2"] From 7bea6f6120351a929767ad864e321ca0550f2288 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 23:25:42 -0700 Subject: [PATCH 012/248] For poetry change: need to put venv in our path so mypy protobuf plugin works --- .github/workflows/update_protobufs.yml | 5 +++++ bin/regen-protobufs.sh | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 86049b7..38ff1d3 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -22,6 +22,11 @@ jobs: tar xvzf nanopb-0.4.6-linux-x86.tar.gz mv nanopb-0.4.6-linux-x86 nanopb-0.4.6 + - name: Install poetry (needed by regen-protobufs.sh) + run: | + python -m pip install --upgrade pip + pip3 install poetry + - name: Re-generate protocol buffers run: | ./bin/regen-protobufs.sh diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index 1f2f23c..ac56608 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -4,8 +4,11 @@ #gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/* #gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/* -./nanopb-0.4.7/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto -./nanopb-0.4.7/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto +# protoc looks for mypy plugin in the python path +source $(poetry env info --path)/bin/activate + +./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto +./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto # workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 From e6a88e055fd02004855e50dda21f138f7ef93492 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 08:26:20 -0700 Subject: [PATCH 013/248] fix #610: bump nanopb to 0.4.8 Including in the Poetry changes because it touches the same lines and I want to avoid hand merging ;-) --- .github/workflows/update_protobufs.yml | 6 +++--- bin/regen-protobufs.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 38ff1d3..5cec898 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -18,9 +18,9 @@ jobs: - name: Download nanopb run: | - wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz - tar xvzf nanopb-0.4.6-linux-x86.tar.gz - mv nanopb-0.4.6-linux-x86 nanopb-0.4.6 + wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz + tar xvzf nanopb-0.4.8-linux-x86.tar.gz + mv nanopb-0.4.8-linux-x86 nanopb-0.4.8 - name: Install poetry (needed by regen-protobufs.sh) run: | diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index ac56608..6b993c8 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -7,8 +7,8 @@ # protoc looks for mypy plugin in the python path source $(poetry env info --path)/bin/activate -./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto -./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto +./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto +./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto # workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 From 62f16d34d4915d8e79b300cc9d3acea984f9c6bd Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 11:56:44 -0700 Subject: [PATCH 014/248] fix BLE scan and connect to work with latest bleak --- .vscode/launch.json | 8 +++++++ meshtastic/__main__.py | 8 ++++++- meshtastic/ble_interface.py | 46 ++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index aca86dd..911eb4d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -76,6 +76,14 @@ "justMyCode": true, "args": ["--debug", "--info"] }, + { + "name": "meshtastic debug BLE", + "type": "python", + "request": "launch", + "module": "meshtastic", + "justMyCode": true, + "args": ["--debug", "--ble", "--info"] + }, { "name": "meshtastic debug set region", "type": "python", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fa71adc..fb12a0c 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1050,7 +1050,7 @@ def common(): meshtastic.util.our_exit("BLE scan finished", 0) return elif args.ble: - client = BLEInterface(args.ble, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) + client = BLEInterface(args.ble_dest, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) elif args.host: try: client = meshtastic.tcp_interface.TCPInterface( @@ -1119,6 +1119,12 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse group.add_argument( "--ble", help="The BLE device address or name to connect to", + action="store_true", + ) + + group.add_argument( + "--ble-dest", + help="The BLE device address or name to connect to", default=None, ) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 1c12758..4b8ddeb 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -7,7 +7,7 @@ import asyncio from threading import Thread, Event from typing import Optional -from bleak import BleakScanner, BleakClient +from bleak import BleakScanner, BleakClient, BLEDevice from meshtastic.mesh_interface import MeshInterface from meshtastic.util import our_exit @@ -35,9 +35,6 @@ class BLEInterface(MeshInterface): def __init__(self, address: Optional[str], noProto: bool = False, debugOut = None, noNodes: bool = False): self.state = BLEInterface.BLEState() - if not address: - return - self.should_read = False logging.debug("Threads starting") @@ -54,10 +51,9 @@ class BLEInterface(MeshInterface): self.client = self.connect(address) self.state.BLE = True logging.debug("BLE connected") - except BLEInterface.BLEError as e: + # except BLEInterface.BLEError as e: + finally: self.close() - our_exit(e.message, 1) - return logging.debug("Mesh init starting") MeshInterface.__init__(self, debugOut = debugOut, noProto = noProto, noNodes = noNodes) @@ -78,33 +74,35 @@ class BLEInterface(MeshInterface): self.should_read = True - def scan(self): - "Scan for available BLE devices" + def scan(self) -> list[BLEDevice]: + """Scan for available BLE devices.""" with BLEClient() as client: - return [ - (x[0], x[1]) for x in (client.discover( + response = client.discover( return_adv = True, - service_uuids = [ SERVICE_UUID ] - )).values() - ] + service_uuids=[SERVICE_UUID] + ) + + devices = response.values() + + # bleak sometimes returns devices we didn't ask for, so filter the response + # to only return true meshtastic devices + # d[0] is the device. d[1] is the advertisement data + devices = list(filter(lambda d: SERVICE_UUID in d[1].service_uuids, devices)) + return list(map(lambda d: d[0], devices)) - def find_device(self, address): - "Find a device by address" - meshtastic_devices = self.scan() + def find_device(self, address: Optional[str]) -> BLEDevice: + """Find a device by address""" + addressed_devices = self.scan() - addressed_devices = list(filter(lambda x: address in (x[1].local_name, x[0].name), meshtastic_devices)) - # If nothing is found try on the address - if len(addressed_devices) == 0: - addressed_devices = list(filter( - lambda x: BLEInterface._sanitize_address(address) == BLEInterface._sanitize_address(x[0].address), - meshtastic_devices)) + if address: + addressed_devices = list(filter(lambda x: address == x.name or address == x.address, addressed_devices)) if len(addressed_devices) == 0: raise BLEInterface.BLEError(f"No Meshtastic BLE peripheral with identifier or address '{address}' found. Try --ble-scan to find it.") if len(addressed_devices) > 1: raise BLEInterface.BLEError(f"More than one Meshtastic BLE peripheral with identifier or address '{address}' found.") - return addressed_devices[0][0] + return addressed_devices[0] def _sanitize_address(address): # pylint: disable=E0213 "Standardize BLE address by removing extraneous characters and lowercasing" From 81266e756b2920d2f2f428fdc3d6ed03049de43c Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 13:52:32 -0700 Subject: [PATCH 015/248] fixes to make Bleak (BLE) work better --- meshtastic/__main__.py | 4 ++-- meshtastic/ble_interface.py | 16 ++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fb12a0c..e6c2362 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1122,11 +1122,11 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse action="store_true", ) - group.add_argument( + outer.add_argument( "--ble-dest", help="The BLE device address or name to connect to", default=None, - ) + ) return parser diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 4b8ddeb..0624db6 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -51,9 +51,9 @@ class BLEInterface(MeshInterface): self.client = self.connect(address) self.state.BLE = True logging.debug("BLE connected") - # except BLEInterface.BLEError as e: - finally: + except BLEInterface.BLEError as e: self.close() + raise e logging.debug("Mesh init starting") MeshInterface.__init__(self, debugOut = debugOut, noProto = noProto, noNodes = noNodes) @@ -112,17 +112,13 @@ class BLEInterface(MeshInterface): .replace(":", "") \ .lower() - def connect(self, address): + def connect(self, address: Optional[str] = None): "Connect to a device by address" + + # Bleak docs recommend always doing a scan before connecting (even if we know addr) device = self.find_device(address) client = BLEClient(device.address) client.connect() - try: - client.pair() - except NotImplementedError: - # Some bluetooth backends do not require explicit pairing. - # See Bleak docs for details on this. - pass return client @@ -212,7 +208,7 @@ class BLEClient(): def __enter__(self): return self - + def __exit__(self, _type, _value, _traceback): self.close() From 8456f36c6bd1e386571099e512232f9d789774fd Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 17:18:04 -0700 Subject: [PATCH 016/248] add NordicSemi Power Profiler Kit 2 device to the USB blacklist --- meshtastic/util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index 86de1e9..3193802 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -24,8 +24,10 @@ import serial.tools.list_ports # type: ignore[import-untyped] from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version -"""Some devices such as a seger jlink or st-link we never want to accidentally open""" -blacklistVids = dict.fromkeys([0x1366, 0x0483]) +"""Some devices such as a seger jlink or st-link we never want to accidentally open +0x1915 NordicSemi (PPK2) +""" +blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915]) """Some devices are highly likely to be meshtastic. 0x239a RAK4631 From a3462e02094d33ce0d736b9d60e4a7f9490aede5 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:20:11 -0700 Subject: [PATCH 017/248] didn't mean to check in built protobufs --- meshtastic/powermon_pb2.py | 28 ------------- meshtastic/powermon_pb2.pyi | 84 ------------------------------------- 2 files changed, 112 deletions(-) delete mode 100644 meshtastic/powermon_pb2.py delete mode 100644 meshtastic/powermon_pb2.pyi diff --git a/meshtastic/powermon_pb2.py b/meshtastic/powermon_pb2.py deleted file mode 100644 index bd91da4..0000000 --- a/meshtastic/powermon_pb2.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/powermon.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\x19meshtastic/powermon.proto\x12\x13meshtastic.PowerMon\"\'\n\x05\x45vent\x12\x13\n\x06states\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_states*\xfb\x01\n\x05State\x12\x08\n\x04None\x10\x00\x12\x11\n\rCPU_DeepSleep\x10\x01\x12\r\n\tCPU_Sleep\x10\x02\x12\r\n\tCPU_Awake\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\x11\n\x0cGPS_LowPower\x10\x80\x10\x12\x14\n\x0fGPS_MediumPower\x10\x80 \x12\x12\n\rGPS_HighPower\x10\x80@Bc\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.powermon_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016PowerMonProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_STATE']._serialized_start=92 - _globals['_STATE']._serialized_end=343 - _globals['_EVENT']._serialized_start=50 - _globals['_EVENT']._serialized_end=89 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/powermon_pb2.pyi b/meshtastic/powermon_pb2.pyi deleted file mode 100644 index df6971a..0000000 --- a/meshtastic/powermon_pb2.pyi +++ /dev/null @@ -1,84 +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 _State: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_State.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - CPU_DeepSleep: _State.ValueType # 1 - CPU_Sleep: _State.ValueType # 2 - CPU_Awake: _State.ValueType # 4 - Lora_RXOn: _State.ValueType # 8 - Lora_TXOn: _State.ValueType # 16 - Lora_RXActive: _State.ValueType # 32 - BT_On: _State.ValueType # 64 - LED_On: _State.ValueType # 128 - Screen_On: _State.ValueType # 256 - Screen_Drawing: _State.ValueType # 512 - Wifi_On: _State.ValueType # 1024 - GPS_LowPower: _State.ValueType # 2048 - GPS_MediumPower: _State.ValueType # 4096 - GPS_HighPower: _State.ValueType # 8192 - -class State(_State, metaclass=_StateEnumTypeWrapper): - """Any significant power changing event in meshtastic should be tagged with a powermon state transition. - If you are making new meshtastic features feel free to add new entries at the end of this definition. - """ - -CPU_DeepSleep: State.ValueType # 1 -CPU_Sleep: State.ValueType # 2 -CPU_Awake: State.ValueType # 4 -Lora_RXOn: State.ValueType # 8 -Lora_TXOn: State.ValueType # 16 -Lora_RXActive: State.ValueType # 32 -BT_On: State.ValueType # 64 -LED_On: State.ValueType # 128 -Screen_On: State.ValueType # 256 -Screen_Drawing: State.ValueType # 512 -Wifi_On: State.ValueType # 1024 -GPS_LowPower: State.ValueType # 2048 -GPS_MediumPower: State.ValueType # 4096 -GPS_HighPower: State.ValueType # 8192 -global___State = State - -@typing.final -class Event(google.protobuf.message.Message): - """ - the log messages will be short and complete (see PowerMon.Event in the protobufs for details). - something like "PwrMon,C,0x00001234,REASON" where the hex number is the bitmask of all current states. - (We use a bitmask for states so that if a log message gets lost it won't be fatal) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - STATES_FIELD_NUMBER: builtins.int - states: builtins.int - """Bitwise-OR of States""" - def __init__( - self, - *, - states: builtins.int | None = ..., - ) -> None: ... - def HasField(self, field_name: typing.Literal["_states", b"_states", "states", b"states"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["_states", b"_states", "states", b"states"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["_states", b"_states"]) -> typing.Literal["states"] | None: ... - -global___Event = Event From 338f00a64a46dc3453c23d53c8fbf43d12649680 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 10:43:33 -0700 Subject: [PATCH 018/248] minor cleanup on observable --- meshtastic/observable.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/meshtastic/observable.py b/meshtastic/observable.py index 2bd2a5b..a980d41 100644 --- a/meshtastic/observable.py +++ b/meshtastic/observable.py @@ -1,9 +1,12 @@ +"""A basic implementation of the observer pattern.""" - -class Event(object): +class Event: """A simple event class.""" -class Observable(object): + def __init__(self, source) -> None: + self.source = source + +class Observable: """A class that represents an observable object. To publish an event call fire(type="progress", percent=50) or whatever. It will call @@ -27,9 +30,8 @@ class Observable(object): Args: **attrs: Arbitrary keyword arguments to be passed to the callback functions. """ - e = Event() - e.source = self + e = Event(self) for k, v in attrs.items(): setattr(e, k, v) for fn in self.callbacks: - fn(e) \ No newline at end of file + fn(e) From 21e5601b2319bad1d735c00b91955cd1f020a34b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 10:43:50 -0700 Subject: [PATCH 019/248] run linter as part of prerelease tests --- bin/prerelease-tests.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/prerelease-tests.sh b/bin/prerelease-tests.sh index 8f89548..ee27cc8 100755 --- a/bin/prerelease-tests.sh +++ b/bin/prerelease-tests.sh @@ -2,6 +2,10 @@ set -e # You may consider running: "pytest -m smoke1" instead of this test. +echo "Linting" + +poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" + echo "Running (crude) prerelease tests to verify sanity" # Use the python environment created by poetry From a1f86a351aaccca47fcc3c50eef3035d7c20300b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 11:24:24 -0700 Subject: [PATCH 020/248] add typing hints --- bin/prerelease-tests.sh | 4 +++- meshtastic/observable.py | 6 ++++++ meshtastic/power_mon.py | 2 +- poetry.lock | 39 ++++++++++++++++++++++++++++++++++----- pyproject.toml | 3 ++- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/bin/prerelease-tests.sh b/bin/prerelease-tests.sh index ee27cc8..27a5a31 100755 --- a/bin/prerelease-tests.sh +++ b/bin/prerelease-tests.sh @@ -3,9 +3,11 @@ set -e # You may consider running: "pytest -m smoke1" instead of this test. echo "Linting" - poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" +echo "Checking types" +poetry run mypy meshtastic/ + echo "Running (crude) prerelease tests to verify sanity" # Use the python environment created by poetry diff --git a/meshtastic/observable.py b/meshtastic/observable.py index a980d41..0d06a73 100644 --- a/meshtastic/observable.py +++ b/meshtastic/observable.py @@ -1,11 +1,17 @@ """A basic implementation of the observer pattern.""" +import typing + class Event: """A simple event class.""" def __init__(self, source) -> None: self.source = source + def __getattr__(self, name: str) -> typing.Any: + """We dynamically add attributes to this class, so stub out __getattr__ so that mypy doesn't complain.""" + pass + class Observable: """A class that represents an observable object. diff --git a/meshtastic/power_mon.py b/meshtastic/power_mon.py index 377ba33..e2bab35 100644 --- a/meshtastic/power_mon.py +++ b/meshtastic/power_mon.py @@ -73,7 +73,7 @@ class PowerMonClient: self.rawData = pd.DataFrame(columns=self.columns) # use time as the index # for efficiency reasons we keep new data in a list - only adding to rawData when needfed - self.newData = [] + self.newData: list[dict] = [] self.power = power = PowerSupply(portName) power.powerOn() diff --git a/poetry.lock b/poetry.lock index a045de4..0c6851f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -814,8 +814,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -846,6 +846,24 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pandas-stubs" +version = "2.2.2.240603" +description = "Type annotations for pandas" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas_stubs-2.2.2.240603-py3-none-any.whl", hash = "sha256:e08ce7f602a4da2bff5a67475ba881c39f2a4d4f7fccc1cba57c6f35a379c6c0"}, + {file = "pandas_stubs-2.2.2.240603.tar.gz", hash = "sha256:2dcc86e8fa6ea41535a4561c1f08b3942ba5267b464eff2e99caeee66f9e4cd1"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.23.5", markers = "python_version >= \"3.9\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\" and python_version < \"3.13\""}, +] +types-pytz = ">=2022.1.1" + [[package]] name = "pdoc3" version = "0.10.0" @@ -1026,8 +1044,8 @@ astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -1349,9 +1367,9 @@ pyserial = "^3.5" [package.source] type = "git" -url = "https://github.com/geeksville/riden.git#ecbda543cf566346dd28558d957b4aa7fe116a83" +url = "https://github.com/geeksville/riden.git#1.2.1" reference = "HEAD" -resolved_reference = "ecbda543cf566346dd28558d957b4aa7fe116a83" +resolved_reference = "a1fbecd54c3346f573277a06489b42957a6fd520" [[package]] name = "setuptools" @@ -1447,6 +1465,17 @@ files = [ {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, ] +[[package]] +name = "types-pytz" +version = "2024.1.0.20240417" +description = "Typing stubs for pytz" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-pytz-2024.1.0.20240417.tar.gz", hash = "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981"}, + {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, +] + [[package]] name = "types-pyyaml" version = "6.0.12.20240311" @@ -1783,4 +1812,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "b893063a1dfe925f901dc45b01d68e255e2bd0ba68bda54de83c875c17b964d8" +content-hash = "8263f20a372fbae7bf88b74a40931cb9e8b6b49d12942d91d960c12142b5a979" diff --git a/pyproject.toml b/pyproject.toml index b2dc9a0..622473a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ types-requests = "^2.31.0.20240406" types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" packaging = "^24.0" -riden = {git = "https://github.com/geeksville/riden.git#ecbda543cf566346dd28558d957b4aa7fe116a83"} +riden = {git = "https://github.com/geeksville/riden.git#1.2.1"} pandas = "^2.2.2" [tool.poetry.group.dev.dependencies] @@ -41,6 +41,7 @@ autopep8 = "^2.1.0" pylint = "^3.2.3" pytap2 = "^2.3.0" pyinstaller = "^6.8.0" +pandas-stubs = "^2.2.2.240603" [tool.poetry.extras] tunnel = ["pytap2"] From cc60f3ebc0fbc55966e90a53ad9343e923019b72 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 12:09:41 -0700 Subject: [PATCH 021/248] begin support for multiple power meter types --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 18 +++++--- meshtastic/powermon/__init__.py | 1 + meshtastic/powermon/riden.py | 58 +++++++++++++++++++++++++ meshtastic/slog/__init__.py | 0 meshtastic/{ => slog}/power_mon.py | 68 +++++------------------------- 6 files changed, 84 insertions(+), 63 deletions(-) create mode 100644 meshtastic/powermon/__init__.py create mode 100644 meshtastic/powermon/riden.py create mode 100644 meshtastic/slog/__init__.py rename meshtastic/{ => slog}/power_mon.py (57%) diff --git a/.vscode/launch.json b/.vscode/launch.json index b093786..3da5923 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -172,7 +172,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-mon", "/dev/ttyUSB1", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + "args": ["--power-riden", "/dev/ttyUSB0", "--port", "/dev/ttyACM0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3db80ba..3593edf 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -21,7 +21,8 @@ from meshtastic import channel_pb2, config_pb2, portnums_pb2, remote_hardware, B from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.power_mon import PowerMonClient +from meshtastic.powermon import RidenPowerSupply +from meshtastic.slog.power_mon import PowerMonClient def onReceive(packet, interface): """Callback invoked when a packet arrives""" @@ -1090,8 +1091,9 @@ def common(): # We assume client is fully connected now onConnected(client) - if args.power_mon: - PowerMonClient(args.power_mon, client) + if args.power_riden: + meter = RidenPowerSupply(args.power_riden) + PowerMonClient(meter, client) have_tunnel = platform.system() == "Linux" @@ -1506,8 +1508,14 @@ def initParser(): ) group.add_argument( - "--power-mon", - help="Capture any power monitor records. You must use --power-mon /dev/ttyUSBxxx to specify which port the power supply is on", + "--power-riden", + help="Talk to a Riden power-supply. You must specify the device path, i.e. /dev/ttyUSBxxx", + ) + + group.add_argument( + "--power-ppk2", + help="Talk to a Nordic Power Profiler Kit 2", + action="store_true", ) group.add_argument( diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py new file mode 100644 index 0000000..d83d496 --- /dev/null +++ b/meshtastic/powermon/__init__.py @@ -0,0 +1 @@ +from .riden import * \ No newline at end of file diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py new file mode 100644 index 0000000..41b82cd --- /dev/null +++ b/meshtastic/powermon/riden.py @@ -0,0 +1,58 @@ +"""code logging power consumption of meshtastic devices.""" + +import logging + +from datetime import datetime + +from riden import Riden + +class PowerMeter: + """Abstract class for power meters.""" + + def getWattHour(self) -> float: + """Get the current watt-hour reading.""" + + + +class PowerSupply(PowerMeter): + """Abstract class for power supplies.""" + + def setMaxCurrent(self, i: float): + """Set the maximum current the supply will provide.""" + + def powerOn(self, v: float): + """Turn on the power supply.""" + + + +class RidenPowerSupply(PowerSupply): + """Interface for talking to programmable bench-top power supplies. + Currently only the Riden supplies are supported (RD6006 tested) + """ + + def __init__(self, portName: str = "/dev/ttyUSB0"): + """Initialize the RidenPowerSupply object. + + Args: + portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0". + """ + self.r = r = Riden(port=portName, baudrate=115200, address=1) + logging.info( + f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." + ) + r.set_date_time(datetime.now()) + + def setMaxCurrent(self, i: float): + """Set the maximum current the supply will provide.""" + self.r.set_i_set(i) + + def powerOn(self, v: float): + """Power on the supply, with reasonable defaults for meshtastic devices.""" + self.r.set_v_set(v) # my WM1110 devboard header is directly connected to the 3.3V rail + self.r.set_output(1) + + def getWattHour(self) -> float: + """Get the current watt-hour reading.""" + self.r.update() + return self.r.wh + diff --git a/meshtastic/slog/__init__.py b/meshtastic/slog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/meshtastic/power_mon.py b/meshtastic/slog/power_mon.py similarity index 57% rename from meshtastic/power_mon.py rename to meshtastic/slog/power_mon.py index e2bab35..c1fd12e 100644 --- a/meshtastic/power_mon.py +++ b/meshtastic/slog/power_mon.py @@ -6,77 +6,35 @@ import atexit from datetime import datetime import pandas as pd -from riden import Riden from meshtastic.mesh_interface import MeshInterface from meshtastic.observable import Event +from meshtastic.powermon import PowerSupply - -class PowerSupply: - """Interface for talking to programmable bench-top power supplies. - Currently only the Riden supplies are supported (RD6006 tested) - """ - - def __init__(self, portName: str = "/dev/ttyUSB0"): - """Initialize the PowerSupply object.""" - self.r = r = Riden(port=portName, baudrate=115200, address=1) - logging.info( - f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." - ) - r.set_date_time(datetime.now()) - - def powerOn(self): - """Power on the supply, with reasonable defaults for meshtastic devices.""" - self.r.set_i_set( - 0.300 - ) # Set current limit to 300mA - hopefully enough to power any board but not break things if there is a short circuit - - # self.r.set_v_set(3.7) # default to a nominal LiPo voltage - self.r.set_v_set(3.3) # my WM1110 devboard header is directly connected to the 3.3V rail - self.r.set_output(1) - - """Get current watts out. - But for most applications you probably want getWattHour() instead (to prevent integration errors from accumulating). - """ - return self.r.get_p_out() - - def getWattHour(self): - """Get current Wh out, since power was turned on.""" - # FIXME: Individual reads seem busted in the riden lib. So for now I just read everything. - self.r.update() - return self.r.wh - # return self.r.get_wh() - - def clearWattHour(self): - """Clear the watt-hour counter FIXME.""" - - -"""Used to match power mon log lines: -INFO | ??:??:?? 7 [Blink] S:PM:0x00000080,reason -""" logRegex = re.compile(".*S:PM:0x([0-9A-Fa-f]+),(.*)") class PowerMonClient: """Client for monitoring power consumption of meshtastic devices.""" - def __init__(self, portName: str, client: MeshInterface) -> None: + def __init__(self, power: PowerSupply, client: MeshInterface) -> None: """Initialize the PowerMonClient object. Args: + power (PowerSupply): The power supply object. client (MeshInterface): The MeshInterface object to monitor. - """ self.client = client self.state = 0 # The current power mon state bitfields self.columns = ["time", "power", "reason", "bitmask"] - self.rawData = pd.DataFrame(columns=self.columns) # use time as the index + self.rawData = pd.DataFrame(columns=self.columns) # use time as the index - # for efficiency reasons we keep new data in a list - only adding to rawData when needfed + # for efficiency reasons we keep new data in a list - only adding to rawData when needed self.newData: list[dict] = [] - self.power = power = PowerSupply(portName) - power.powerOn() + self.power = power + power.setMaxCurrent(0.300) # Set current limit to 300mA - hopefully enough to power any board but not break things if there is a short circuit + power.powerOn(3.3) # Used to calculate watts over an interval self.prevPowerTime = datetime.now() @@ -89,7 +47,6 @@ class PowerMonClient: Returns: pd.DataFrame: The raw data. - """ df = pd.DataFrame(self.newData, columns=self.columns) self.rawData = pd.concat([self.rawData, df], ignore_index=True) @@ -107,8 +64,7 @@ class PowerMonClient: """Callback function for handling log messages. Args: - message (str): The log message. - + ev (Event): The log event. """ m = logRegex.match(ev.message) if m: @@ -124,9 +80,7 @@ class PowerMonClient: Args: mask (int): The power mon state bitfields. reason (str): The reason for the power mon state change. - """ - now = datetime.now() nowWattHour = self.power.getWattHour() watts = ( @@ -139,5 +93,5 @@ class PowerMonClient: self.state = mask self.newData.append( - {"time": now, "power": watts, "reason": reason, "bitmask": mask}) - # self.getRawData() + {"time": now, "power": watts, "reason": reason, "bitmask": mask} + ) From 362c1f3d2a93de30c5a18f346a2dd6e164675190 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 12:09:49 -0700 Subject: [PATCH 022/248] remove python 3.8 --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39f8992..82d1c99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,6 @@ jobs: strategy: matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" @@ -56,7 +55,6 @@ jobs: strategy: matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" From be74c3eea0be7f96758957a3af67935237775f01 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 12:19:06 -0700 Subject: [PATCH 023/248] fix linter warnings --- meshtastic/observable.py | 2 +- meshtastic/powermon/__init__.py | 4 +++- meshtastic/powermon/riden.py | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/meshtastic/observable.py b/meshtastic/observable.py index 0d06a73..d57330c 100644 --- a/meshtastic/observable.py +++ b/meshtastic/observable.py @@ -10,7 +10,7 @@ class Event: def __getattr__(self, name: str) -> typing.Any: """We dynamically add attributes to this class, so stub out __getattr__ so that mypy doesn't complain.""" - pass + class Observable: """A class that represents an observable object. diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index d83d496..d8b4104 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -1 +1,3 @@ -from .riden import * \ No newline at end of file +"""Support for logging from power meters/supplies.""" + +from .riden import * diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py index 41b82cd..8d7c131 100644 --- a/meshtastic/powermon/riden.py +++ b/meshtastic/powermon/riden.py @@ -55,4 +55,3 @@ class RidenPowerSupply(PowerSupply): """Get the current watt-hour reading.""" self.r.update() return self.r.wh - From 0e45637f2c3efd483b40b2b17ec93c5d00b5ecf8 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 14:46:08 -0700 Subject: [PATCH 024/248] generalize the powermon stuff to become structured logging --- .vscode/settings.json | 3 + meshtastic/__main__.py | 13 +++-- meshtastic/powermon/riden.py | 29 ++++++++-- meshtastic/slog/__init__.py | 3 + meshtastic/slog/power_mon.py | 97 --------------------------------- meshtastic/slog/slog.py | 103 +++++++++++++++++++++++++++++++++++ poetry.lock | 13 ++++- pyproject.toml | 1 + 8 files changed, 154 insertions(+), 108 deletions(-) delete mode 100644 meshtastic/slog/power_mon.py create mode 100644 meshtastic/slog/slog.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 5deb062..a1fd574 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { "cSpell.words": [ + "bitmask", + "boardid", "Meshtastic", + "powermon", "TORADIO", "Vids" ], diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3593edf..4a21e85 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -22,7 +22,7 @@ from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface from meshtastic.powermon import RidenPowerSupply -from meshtastic.slog.power_mon import PowerMonClient +from meshtastic.slog import StructuredLogger def onReceive(packet, interface): """Callback invoked when a packet arrives""" @@ -1087,21 +1087,24 @@ def common(): f"Error connecting to localhost:{ex}", 1 ) - # We assume client is fully connected now onConnected(client) + meter = None # assume no power meter if args.power_riden: meter = RidenPowerSupply(args.power_riden) - PowerMonClient(meter, client) + StructuredLogger(client, meter) have_tunnel = platform.system() == "Linux" if ( args.noproto or args.reply or (have_tunnel and args.tunnel) or args.listen ): # loop until someone presses ctrlc - while True: - time.sleep(1000) + try: + while True: + time.sleep(1000) + except KeyboardInterrupt: + logging.info("Exiting due to keyboard interrupt") # don't call exit, background threads might be running still # sys.exit(0) diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py index 8d7c131..1dd65bc 100644 --- a/meshtastic/powermon/riden.py +++ b/meshtastic/powermon/riden.py @@ -1,7 +1,7 @@ """code logging power consumption of meshtastic devices.""" import logging - +import math from datetime import datetime from riden import Riden @@ -9,8 +9,27 @@ from riden import Riden class PowerMeter: """Abstract class for power meters.""" - def getWattHour(self) -> float: - """Get the current watt-hour reading.""" + def __init__(self): + """Initialize the PowerMeter object.""" + self.prevPowerTime = datetime.now() + self.prevWattHour = self._getRawWattHour() + + def getWatts(self) -> float: + """Get the total amount of power that has been consumed since the previous call of this method""" + now = datetime.now() + nowWattHour = self._getRawWattHour() + watts = ( + (nowWattHour - self.prevWattHour) + / (now - self.prevPowerTime).total_seconds() + * 3600 + ) + self.prevPowerTime = now + self.prevWattHour = nowWattHour + return watts + + def _getRawWattHour(self) -> float: + """Get the current watt-hour reading (without any offset correction).""" + return math.nan @@ -33,7 +52,6 @@ class RidenPowerSupply(PowerSupply): def __init__(self, portName: str = "/dev/ttyUSB0"): """Initialize the RidenPowerSupply object. - Args: portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0". """ self.r = r = Riden(port=portName, baudrate=115200, address=1) @@ -41,6 +59,7 @@ class RidenPowerSupply(PowerSupply): f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." ) r.set_date_time(datetime.now()) + super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works def setMaxCurrent(self, i: float): """Set the maximum current the supply will provide.""" @@ -51,7 +70,7 @@ class RidenPowerSupply(PowerSupply): self.r.set_v_set(v) # my WM1110 devboard header is directly connected to the 3.3V rail self.r.set_output(1) - def getWattHour(self) -> float: + def _getRawWattHour(self) -> float: """Get the current watt-hour reading.""" self.r.update() return self.r.wh diff --git a/meshtastic/slog/__init__.py b/meshtastic/slog/__init__.py index e69de29..a96ae8e 100644 --- a/meshtastic/slog/__init__.py +++ b/meshtastic/slog/__init__.py @@ -0,0 +1,3 @@ +"""Structured logging framework (see dev docs for more info)""" + +from .slog import StructuredLogger diff --git a/meshtastic/slog/power_mon.py b/meshtastic/slog/power_mon.py deleted file mode 100644 index c1fd12e..0000000 --- a/meshtastic/slog/power_mon.py +++ /dev/null @@ -1,97 +0,0 @@ -"""code logging power consumption of meshtastic devices.""" - -import logging -import re -import atexit -from datetime import datetime - -import pandas as pd - -from meshtastic.mesh_interface import MeshInterface -from meshtastic.observable import Event -from meshtastic.powermon import PowerSupply - -logRegex = re.compile(".*S:PM:0x([0-9A-Fa-f]+),(.*)") - - -class PowerMonClient: - """Client for monitoring power consumption of meshtastic devices.""" - - def __init__(self, power: PowerSupply, client: MeshInterface) -> None: - """Initialize the PowerMonClient object. - - Args: - power (PowerSupply): The power supply object. - client (MeshInterface): The MeshInterface object to monitor. - """ - self.client = client - self.state = 0 # The current power mon state bitfields - self.columns = ["time", "power", "reason", "bitmask"] - self.rawData = pd.DataFrame(columns=self.columns) # use time as the index - - # for efficiency reasons we keep new data in a list - only adding to rawData when needed - self.newData: list[dict] = [] - - self.power = power - power.setMaxCurrent(0.300) # Set current limit to 300mA - hopefully enough to power any board but not break things if there is a short circuit - power.powerOn(3.3) - - # Used to calculate watts over an interval - self.prevPowerTime = datetime.now() - self.prevWattHour = power.getWattHour() - atexit.register(self._exitHandler) - client.onLogMessage.subscribe(self._onLogMessage) - - def getRawData(self) -> pd.DataFrame: - """Get the raw data. - - Returns: - pd.DataFrame: The raw data. - """ - df = pd.DataFrame(self.newData, columns=self.columns) - self.rawData = pd.concat([self.rawData, df], ignore_index=True) - self.newData = [] - - return self.rawData - - def _exitHandler(self) -> None: - """Exit handler.""" - fn = "/tmp/powermon.csv" # Find a better place - logging.info(f"Storing PowerMon raw data in {fn}") - self.getRawData().to_csv(fn) - - def _onLogMessage(self, ev: Event) -> None: - """Callback function for handling log messages. - - Args: - ev (Event): The log event. - """ - m = logRegex.match(ev.message) - if m: - mask = int(m.group(1), 16) - reason = m.group(2) - logging.debug(f"PowerMon state: 0x{mask:x}, reason: {reason}") - if mask != self.state: - self._storeRecord(mask, reason) - - def _storeRecord(self, mask: int, reason: str) -> None: - """Store a power mon record. - - Args: - mask (int): The power mon state bitfields. - reason (str): The reason for the power mon state change. - """ - now = datetime.now() - nowWattHour = self.power.getWattHour() - watts = ( - (nowWattHour - self.prevWattHour) - / (now - self.prevPowerTime).total_seconds() - * 3600 - ) - self.prevPowerTime = now - self.prevWattHour = nowWattHour - self.state = mask - - self.newData.append( - {"time": now, "power": watts, "reason": reason, "bitmask": mask} - ) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py new file mode 100644 index 0000000..17910e7 --- /dev/null +++ b/meshtastic/slog/slog.py @@ -0,0 +1,103 @@ +"""code logging power consumption of meshtastic devices.""" + +import logging +import re +import atexit +from datetime import datetime +from dataclasses import dataclass + +import parse +import pandas as pd + +from meshtastic.mesh_interface import MeshInterface +from meshtastic.observable import Event +from meshtastic.powermon import PowerMeter + + +@dataclass(init=False) +class LogDef: + """Log definition.""" + code: str # i.e. PM or B or whatever... see meshtastic slog documentation + format: str # A format string that can be used to parse the arguments + + def __init__(self, code: str, format: str) -> None: + """Initialize the LogDef object. + + code (str): The code. + format (str): The format. + """ + self.code = code + self.format = parse.compile(format) + +"""A dictionary mapping from logdef code to logdef""" +log_defs = {d.code: d for d in [ + LogDef("B", "{boardid:d},{version}"), + LogDef("PM", "{bitmask:d},{reason}") + ]} +log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") + + +class StructuredLogger: + """Sniffs device logs for structured log messages, extracts those into pandas/CSV format.""" + + def __init__(self, client: MeshInterface, pMeter: PowerMeter = None) -> None: + """Initialize the PowerMonClient object. + + power (PowerSupply): The power supply object. + client (MeshInterface): The MeshInterface object to monitor. + """ + self.client = client + self.pMeter = pMeter + self.columns = ["time", "power"] + self.rawData = pd.DataFrame(columns=self.columns) # use time as the index + + # for efficiency reasons we keep new data in a list - only adding to rawData when needed + self.newData: list[dict] = [] + + atexit.register(self._exitHandler) + client.onLogMessage.subscribe(self._onLogMessage) + + def getRawData(self) -> pd.DataFrame: + """Get the raw data. + + Returns + ------- + pd.DataFrame: The raw data. + """ + df = pd.DataFrame(self.newData, columns=self.columns) + self.rawData = pd.concat([self.rawData, df], ignore_index=True) + self.newData = [] + + return self.rawData + + def _exitHandler(self) -> None: + """Exit handler.""" + fn = "/tmp/powermon.slog" # Find a better place + logging.info(f"Storing slog in {fn}") + self.getRawData().to_csv(fn) + + def _onLogMessage(self, ev: Event) -> None: + """Handle log messages. + + ev (Event): The log event. + """ + m = log_regex.match(ev.message) + if m: + src = m.group(1) + args = m.group(2) + + args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match + logging.debug(f"SLog {src}, reason: {args}") + d = log_defs.get(src) + if d: + r = d.format.parse(args) # get the values with the correct types + if r: + di = r.named + di["time"] = datetime.now() + if self.pMeter: # if we have a power meter include a fresh power reading + di["power"] = self.pMeter.getWatts() + self.newData.append(di) + else: + logging.warning(f"Failed to parse slog {ev.message} with {d.format}") + else: + logging.warning(f"Unknown Structured Log: {ev.message}") diff --git a/poetry.lock b/poetry.lock index 0c6851f..b2ea4c6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -864,6 +864,17 @@ numpy = [ ] types-pytz = ">=2022.1.1" +[[package]] +name = "parse" +version = "1.20.2" +description = "parse() is the opposite of format()" +optional = false +python-versions = "*" +files = [ + {file = "parse-1.20.2-py2.py3-none-any.whl", hash = "sha256:967095588cb802add9177d0c0b6133b5ba33b1ea9007ca800e526f42a85af558"}, + {file = "parse-1.20.2.tar.gz", hash = "sha256:b41d604d16503c79d81af5165155c0b20f6c8d6c559efa66b4b695c3e5a0a0ce"}, +] + [[package]] name = "pdoc3" version = "0.10.0" @@ -1812,4 +1823,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "8263f20a372fbae7bf88b74a40931cb9e8b6b49d12942d91d960c12142b5a979" +content-hash = "109915f24859629e5ec50dd761be8fcaa72fb327d724da8f18f266e9f2a3e4db" diff --git a/pyproject.toml b/pyproject.toml index 622473a..2f53954 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ types-pyyaml = "^6.0.12.20240311" packaging = "^24.0" riden = {git = "https://github.com/geeksville/riden.git#1.2.1"} pandas = "^2.2.2" +parse = "^1.20.2" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From 79c65c17062f9b400dd9bbd14f57b208b42092c9 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 16:02:59 -0700 Subject: [PATCH 025/248] make slog nicely add new rows --- meshtastic/slog/slog.py | 16 ++++++++++++++-- protobufs | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 17910e7..951ae86 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -50,6 +50,7 @@ class StructuredLogger: self.pMeter = pMeter self.columns = ["time", "power"] self.rawData = pd.DataFrame(columns=self.columns) # use time as the index + # self.rawData.set_index("time", inplace=True) # for efficiency reasons we keep new data in a list - only adding to rawData when needed self.newData: list[dict] = [] @@ -64,8 +65,18 @@ class StructuredLogger: ------- pd.DataFrame: The raw data. """ - df = pd.DataFrame(self.newData, columns=self.columns) - self.rawData = pd.concat([self.rawData, df], ignore_index=True) + + df = pd.DataFrame(self.newData) + + # We prefer some columns to be integers + intcols = [ "bitmask" ] + for c in intcols: + if c in df: + df[c] = df[c].astype('Int64') + + # df.set_index("time") + # Add new data, creating new columns as needed (an outer join) + self.rawData = pd.concat([self.rawData, df], axis=0, ignore_index=True) self.newData = [] return self.rawData @@ -97,6 +108,7 @@ class StructuredLogger: if self.pMeter: # if we have a power meter include a fresh power reading di["power"] = self.pMeter.getWatts() self.newData.append(di) + self.getRawData() else: logging.warning(f"Failed to parse slog {ev.message} with {d.format}") else: diff --git a/protobufs b/protobufs index bfde27a..a82df22 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit bfde27a4ea5cfd0f60ffe961b5ce249aaf54c182 +Subproject commit a82df2239a9dc4b9d43debeb4e87135b13784ca5 From 9c657c6c8a2024a31c5acb5e3bf0cd4f0ed87759 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 23:16:05 -0700 Subject: [PATCH 026/248] switch to latest protobufs --- protobufs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protobufs b/protobufs index a82df22..4da558d 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a82df2239a9dc4b9d43debeb4e87135b13784ca5 +Subproject commit 4da558d0f73c46ef91b74431facee73c09affbfc From 51c6c2cae135f04c184d3cc04a97e51ad7c92c8b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 22 Jun 2024 23:16:43 -0700 Subject: [PATCH 027/248] The github action for building protobufs is using 0.4.6 so we should match --- bin/regen-protobufs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index 1f2f23c..aff4ff6 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -4,8 +4,8 @@ #gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/* #gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/* -./nanopb-0.4.7/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto -./nanopb-0.4.7/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto +./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto +./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto # workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 From 67e1e7c3184aea49c9b7ec9a54d766a6b6595899 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:23:34 -0700 Subject: [PATCH 028/248] move mypy and type info into dev-time only dependencies thx @njh # Conflicts: # poetry.lock # pyproject.toml --- poetry.lock | 227 +++++++++++++++++++++---------------------------- pyproject.toml | 15 ++-- 2 files changed, 106 insertions(+), 136 deletions(-) diff --git a/poetry.lock b/poetry.lock index b2ea4c6..464c3eb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -57,13 +57,13 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "autopep8" -version = "2.3.0" +version = "2.3.1" description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" optional = false python-versions = ">=3.8" files = [ - {file = "autopep8-2.3.0-py2.py3-none-any.whl", hash = "sha256:b716efa70cbafbf4a2c9c5ec1cabfa037a68f9e30b04c74ffa5864dd49b8f7d2"}, - {file = "autopep8-2.3.0.tar.gz", hash = "sha256:5cfe45eb3bef8662f6a3c7e28b7c0310c7310d340074b7f0f28f9810b44b7ef4"}, + {file = "autopep8-2.3.1-py2.py3-none-any.whl", hash = "sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d"}, + {file = "autopep8-2.3.1.tar.gz", hash = "sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda"}, ] [package.dependencies] @@ -254,63 +254,63 @@ files = [ [[package]] name = "coverage" -version = "7.5.3" +version = "7.5.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, - {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, - {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, - {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, - {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, - {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, - {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, - {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, - {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, - {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, - {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, - {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, - {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, - {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.dependencies] @@ -404,13 +404,13 @@ test = ["pytest (>=6)"] [[package]] name = "hypothesis" -version = "6.103.2" +version = "6.104.0" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.103.2-py3-none-any.whl", hash = "sha256:629b7cdeca8c225933739f99879caba21949000d2c919c8b4585e01048b3bc73"}, - {file = "hypothesis-6.103.2.tar.gz", hash = "sha256:83504e31e90a0d7d6e8eb93e51525dc1a48d79c932a50ad6035e29f8295328cd"}, + {file = "hypothesis-6.104.0-py3-none-any.whl", hash = "sha256:4aaa38b57625abae0d377b2460b80a5847504dcce22985e3381e4373079d45d0"}, + {file = "hypothesis-6.104.0.tar.gz", hash = "sha256:f3f376491380aab841d706c562034c0118616dca7ce23e07b1a744c99f38d26b"}, ] [package.dependencies] @@ -419,10 +419,10 @@ exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.54)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.55)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] -crosshair = ["crosshair-tool (>=0.0.54)", "hypothesis-crosshair (>=0.0.4)"] +crosshair = ["crosshair-tool (>=0.0.55)", "hypothesis-crosshair (>=0.0.4)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] @@ -448,13 +448,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.0" +version = "7.2.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, - {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, + {file = "importlib_metadata-7.2.1-py3-none-any.whl", hash = "sha256:ffef94b0b66046dd8ea2d619b701fe978d9264d38f3998bc4c27ec3b146a87c8"}, + {file = "importlib_metadata-7.2.1.tar.gz", hash = "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68"}, ] [package.dependencies] @@ -637,38 +637,38 @@ pyserial = ">=3.1" [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] @@ -814,8 +814,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -846,24 +846,6 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] -[[package]] -name = "pandas-stubs" -version = "2.2.2.240603" -description = "Type annotations for pandas" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas_stubs-2.2.2.240603-py3-none-any.whl", hash = "sha256:e08ce7f602a4da2bff5a67475ba881c39f2a4d4f7fccc1cba57c6f35a379c6c0"}, - {file = "pandas_stubs-2.2.2.240603.tar.gz", hash = "sha256:2dcc86e8fa6ea41535a4561c1f08b3942ba5267b464eff2e99caeee66f9e4cd1"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.23.5", markers = "python_version >= \"3.9\" and python_version < \"3.12\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\" and python_version < \"3.13\""}, -] -types-pytz = ">=2022.1.1" - [[package]] name = "parse" version = "1.20.2" @@ -1055,8 +1037,8 @@ astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -1380,17 +1362,17 @@ pyserial = "^3.5" type = "git" url = "https://github.com/geeksville/riden.git#1.2.1" reference = "HEAD" -resolved_reference = "a1fbecd54c3346f573277a06489b42957a6fd520" +resolved_reference = "27fd58f069a089676dcaaea2ccb8dc8d24e4c6d9" [[package]] name = "setuptools" -version = "70.1.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, - {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] @@ -1476,17 +1458,6 @@ files = [ {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, ] -[[package]] -name = "types-pytz" -version = "2024.1.0.20240417" -description = "Typing stubs for pytz" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-pytz-2024.1.0.20240417.tar.gz", hash = "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981"}, - {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, -] - [[package]] name = "types-pyyaml" version = "6.0.12.20240311" @@ -1823,4 +1794,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "109915f24859629e5ec50dd761be8fcaa72fb327d724da8f18f266e9f2a3e4db" +content-hash = "cc81bcd3e4671bde3375f2f08334d6a3b87b38c97f2676d7266cab980082659e" diff --git a/pyproject.toml b/pyproject.toml index 2f53954..c5c4b8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,13 +21,6 @@ pyparsing = "^3.1.2" pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" -mypy = "^1.10.0" -mypy-protobuf = "^3.6.0" -types-protobuf = "^5.26.0.20240422" -types-tabulate = "^0.9.0.20240106" -types-requests = "^2.31.0.20240406" -types-setuptools = "^69.5.0.20240423" -types-pyyaml = "^6.0.12.20240311" packaging = "^24.0" riden = {git = "https://github.com/geeksville/riden.git#1.2.1"} pandas = "^2.2.2" @@ -42,7 +35,13 @@ autopep8 = "^2.1.0" pylint = "^3.2.3" pytap2 = "^2.3.0" pyinstaller = "^6.8.0" -pandas-stubs = "^2.2.2.240603" +mypy = "^1.10.0" +mypy-protobuf = "^3.6.0" +types-protobuf = "^5.26.0.20240422" +types-tabulate = "^0.9.0.20240106" +types-requests = "^2.31.0.20240406" +types-setuptools = "^69.5.0.20240423" +types-pyyaml = "^6.0.12.20240311" [tool.poetry.extras] tunnel = ["pytap2"] From 46edd78f92383eb75c8d68dc4f1c3d743b4b5ad5 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:25:52 -0700 Subject: [PATCH 029/248] For poetry change: need to put venv in our path so mypy protobuf plugin works # Conflicts: # bin/regen-protobufs.sh --- .github/workflows/update_protobufs.yml | 5 +++++ bin/regen-protobufs.sh | 3 +++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 86049b7..38ff1d3 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -22,6 +22,11 @@ jobs: tar xvzf nanopb-0.4.6-linux-x86.tar.gz mv nanopb-0.4.6-linux-x86 nanopb-0.4.6 + - name: Install poetry (needed by regen-protobufs.sh) + run: | + python -m pip install --upgrade pip + pip3 install poetry + - name: Re-generate protocol buffers run: | ./bin/regen-protobufs.sh diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index aff4ff6..ac56608 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -4,6 +4,9 @@ #gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/* #gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/* +# protoc looks for mypy plugin in the python path +source $(poetry env info --path)/bin/activate + ./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto ./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto From 7b18fd599c32bc3e16294d226ec0dad8504cd88c Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 08:17:54 -0700 Subject: [PATCH 030/248] remove observable - switch because we are already using pubsub elsewhere --- meshtastic/__init__.py | 1 + meshtastic/mesh_interface.py | 17 ++++++++++---- meshtastic/observable.py | 43 ---------------------------------- meshtastic/slog/slog.py | 18 +++++++------- meshtastic/stream_interface.py | 3 --- 5 files changed, 23 insertions(+), 59 deletions(-) delete mode 100644 meshtastic/observable.py diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index a5075bc..4745d2d 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -31,6 +31,7 @@ type of packet, you should subscribe to the full topic name. If you want to see - meshtastic.receive.user(packet) - 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 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 diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 0bc67ba..60a26ab 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -40,7 +40,6 @@ from meshtastic.util import ( stripnl, message_to_json, ) -from meshtastic.observable import Observable class MeshInterface: # pylint: disable=R0902 """Interface class for meshtastic devices @@ -71,7 +70,6 @@ class MeshInterface: # pylint: disable=R0902 self.nodes: Optional[Dict[str,Dict]] = None # FIXME self.isConnected: threading.Event = threading.Event() self.noProto: bool = noProto - self.onLogMessage = Observable() self.localNode: meshtastic.node.Node = meshtastic.node.Node(self, -1) # We fixup nodenum later self.myInfo: Optional[mesh_pb2.MyNodeInfo] = None # We don't have device info yet self.metadata: Optional[mesh_pb2.DeviceMetadata] = None # We don't have device metadata yet @@ -93,6 +91,12 @@ class MeshInterface: # pylint: disable=R0902 self.queue: collections.OrderedDict = collections.OrderedDict() self._localChannels = None + # We could have just not passed in debugOut to MeshInterface, and instead told consumers to subscribe to + # the meshtastic.log.line publish instead. Alas though changing that now would be a breaking API change + # for any external consumers of the library. + if debugOut: + pub.subscribe(MeshInterface._printLogLine, "meshtastic.log.line") + def close(self): """Shutdown this interface""" if self.heartbeatTimer: @@ -112,9 +116,14 @@ class MeshInterface: # pylint: disable=R0902 logging.error(f"Traceback: {traceback}") self.close() - def _handleLogLine(self, line): + @staticmethod + def _printLogLine(line, interface): + """Print a line of log output""" + interface.debugOut.write(line + "\n") + + def _handleLogLine(self, line: str) -> None: """Handle a line of log output from the device.""" - self.onLogMessage.fire(message=line) + pub.sendMessage("meshtastic.log.line", line=line, interface=self) def showInfo(self, file=sys.stdout) -> str: # pylint: disable=W0613 """Show human readable summary about this object""" diff --git a/meshtastic/observable.py b/meshtastic/observable.py deleted file mode 100644 index d57330c..0000000 --- a/meshtastic/observable.py +++ /dev/null @@ -1,43 +0,0 @@ -"""A basic implementation of the observer pattern.""" - -import typing - -class Event: - """A simple event class.""" - - def __init__(self, source) -> None: - self.source = source - - def __getattr__(self, name: str) -> typing.Any: - """We dynamically add attributes to this class, so stub out __getattr__ so that mypy doesn't complain.""" - - -class Observable: - """A class that represents an observable object. - - To publish an event call fire(type="progress", percent=50) or whatever. It will call - """ - - def __init__(self): - """Initialize the Observable object.""" - self.callbacks = [] - - def subscribe(self, callback): - """Subscribe to the observable object. - - Args: - callback (function): The callback function to be called when the event is fired. - """ - self.callbacks.append(callback) - - def fire(self, **attrs): - """Fire the event. - - Args: - **attrs: Arbitrary keyword arguments to be passed to the callback functions. - """ - e = Event(self) - for k, v in attrs.items(): - setattr(e, k, v) - for fn in self.callbacks: - fn(e) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 951ae86..ab47414 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -8,9 +8,9 @@ from dataclasses import dataclass import parse import pandas as pd +from pubsub import pub # type: ignore[import-untyped] from meshtastic.mesh_interface import MeshInterface -from meshtastic.observable import Event from meshtastic.powermon import PowerMeter @@ -20,14 +20,14 @@ class LogDef: code: str # i.e. PM or B or whatever... see meshtastic slog documentation format: str # A format string that can be used to parse the arguments - def __init__(self, code: str, format: str) -> None: + def __init__(self, code: str, fmt: str) -> None: """Initialize the LogDef object. code (str): The code. format (str): The format. """ self.code = code - self.format = parse.compile(format) + self.format = parse.compile(fmt) """A dictionary mapping from logdef code to logdef""" log_defs = {d.code: d for d in [ @@ -56,7 +56,7 @@ class StructuredLogger: self.newData: list[dict] = [] atexit.register(self._exitHandler) - client.onLogMessage.subscribe(self._onLogMessage) + pub.subscribe(self._onLogMessage, "meshtastic.log.line") def getRawData(self) -> pd.DataFrame: """Get the raw data. @@ -87,12 +87,12 @@ class StructuredLogger: logging.info(f"Storing slog in {fn}") self.getRawData().to_csv(fn) - def _onLogMessage(self, ev: Event) -> None: + def _onLogMessage(self, line: str, interface: MeshInterface) -> None: # pylint: disable=unused-argument """Handle log messages. - ev (Event): The log event. + line (str): the line of log output """ - m = log_regex.match(ev.message) + m = log_regex.match(line) if m: src = m.group(1) args = m.group(2) @@ -110,6 +110,6 @@ class StructuredLogger: self.newData.append(di) self.getRawData() else: - logging.warning(f"Failed to parse slog {ev.message} with {d.format}") + logging.warning(f"Failed to parse slog {line} with {d.format}") else: - logging.warning(f"Unknown Structured Log: {ev.message}") + logging.warning(f"Unknown Structured Log: {line}") diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index c05a318..18d6e9f 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -142,9 +142,6 @@ class StreamInterface(MeshInterface): else: self.cur_log_line += utf - if self.debugOut is not None: - self.debugOut.write(utf) - def __reader(self): """The reader thread that reads bytes from our stream""" logging.debug("in __reader()") From b7f7a40192e23944415c228e67637bf9684d6897 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 08:18:16 -0700 Subject: [PATCH 031/248] document why using python 3.9 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c5c4b8a..368c265 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" readme = "README.md" [tool.poetry.dependencies] -python = "^3.9,<3.13" # was 3.7 for production but, 3.8 is needed for pytap2, 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +python = "^3.9,<3.13" # 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason pyserial = "^3.5" protobuf = ">=5.26.0" dotmap = "^1.3.30" From 6c0e978470dd5e8704d9676adfe9b9bf9df8d733 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 08:18:27 -0700 Subject: [PATCH 032/248] debugging config tweaks --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3da5923..49a3d71 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -163,7 +163,7 @@ "type": "python", "request": "launch", "module": "meshtastic", - "justMyCode": true, + "justMyCode": false, "args": ["--noproto", "--seriallog", "stdout"] }, { From 8b781d32453e5a3329c7c26ea61009e59dd776e0 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 08:26:20 -0700 Subject: [PATCH 033/248] fix #610: bump nanopb to 0.4.8 Including in the Poetry changes because it touches the same lines and I want to avoid hand merging ;-) --- .github/workflows/update_protobufs.yml | 6 +++--- bin/regen-protobufs.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 38ff1d3..5cec898 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -18,9 +18,9 @@ jobs: - name: Download nanopb run: | - wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz - tar xvzf nanopb-0.4.6-linux-x86.tar.gz - mv nanopb-0.4.6-linux-x86 nanopb-0.4.6 + wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz + tar xvzf nanopb-0.4.8-linux-x86.tar.gz + mv nanopb-0.4.8-linux-x86 nanopb-0.4.8 - name: Install poetry (needed by regen-protobufs.sh) run: | diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index ac56608..6b993c8 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -7,8 +7,8 @@ # protoc looks for mypy plugin in the python path source $(poetry env info --path)/bin/activate -./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto -./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto +./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto +./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto # workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 From 1add2934148226111129687dff65a00990cc9385 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 19 Jun 2024 14:45:59 -0700 Subject: [PATCH 034/248] Add a whitelist of known meshtastic USB VIDs to use a default serial ports. Initially only RAK4631 and heltec tracker are listed --- meshtastic/util.py | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index 14f6a54..86de1e9 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -24,8 +24,14 @@ import serial.tools.list_ports # type: ignore[import-untyped] from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version -"""Some devices such as a seger jlink we never want to accidentally open""" -blacklistVids = dict.fromkeys([0x1366]) +"""Some devices such as a seger jlink or st-link we never want to accidentally open""" +blacklistVids = dict.fromkeys([0x1366, 0x0483]) + +"""Some devices are highly likely to be meshtastic. +0x239a RAK4631 +0x303a Heltec tracker""" +whitelistVids = dict.fromkeys([0x239a, 0x303a]) + def quoteBooleans(a_string): """Quote booleans @@ -130,19 +136,35 @@ def findPorts(eliminate_duplicates: bool=False) -> List[str]: Returns: list -- a list of device paths """ - l = list( + all_ports = serial.tools.list_ports.comports() + + # look for 'likely' meshtastic devices + ports = list( map( lambda port: port.device, filter( - lambda port: port.vid is not None and port.vid not in blacklistVids, - serial.tools.list_ports.comports(), + lambda port: port.vid is not None and port.vid in whitelistVids, + all_ports, ), ) ) - l.sort() + + # if no likely devices, just list everything not blacklisted + if len(ports) == 0: + ports = list( + map( + lambda port: port.device, + filter( + lambda port: port.vid is not None and port.vid not in blacklistVids, + all_ports, + ), + ) + ) + + ports.sort() if eliminate_duplicates: - l = eliminate_duplicate_port(l) - return l + ports = eliminate_duplicate_port(ports) + return ports class dotdict(dict): From 5ff4025ed615146605c981539b97fa4e75b03501 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 17:18:04 -0700 Subject: [PATCH 035/248] add NordicSemi Power Profiler Kit 2 device to the USB blacklist --- meshtastic/util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index 86de1e9..3193802 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -24,8 +24,10 @@ import serial.tools.list_ports # type: ignore[import-untyped] from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version -"""Some devices such as a seger jlink or st-link we never want to accidentally open""" -blacklistVids = dict.fromkeys([0x1366, 0x0483]) +"""Some devices such as a seger jlink or st-link we never want to accidentally open +0x1915 NordicSemi (PPK2) +""" +blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915]) """Some devices are highly likely to be meshtastic. 0x239a RAK4631 From ea18057c1f8d39cc1b5571150bb62dcbe4940b10 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 23 Jun 2024 18:42:15 -0700 Subject: [PATCH 036/248] Add support for NRF PPK2 power testing board. --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 17 +++++++++- meshtastic/powermon/__init__.py | 4 ++- meshtastic/powermon/power_supply.py | 49 +++++++++++++++++++++++++++++ meshtastic/powermon/ppk2.py | 47 +++++++++++++++++++++++++++ meshtastic/powermon/riden.py | 48 +++------------------------- poetry.lock | 16 +++++++++- pyproject.toml | 1 + 8 files changed, 137 insertions(+), 47 deletions(-) create mode 100644 meshtastic/powermon/power_supply.py create mode 100644 meshtastic/powermon/ppk2.py diff --git a/.vscode/launch.json b/.vscode/launch.json index 49a3d71..f833f3a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -172,7 +172,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-riden", "/dev/ttyUSB0", "--port", "/dev/ttyACM0", "--noproto", "--seriallog", "stdout"] + "args": ["--power-ppk", "--power-voltage", "3.3", "--port", "/dev/ttyACM0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 4a21e85..323d13e 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -21,7 +21,7 @@ from meshtastic import channel_pb2, config_pb2, portnums_pb2, remote_hardware, B from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.powermon import RidenPowerSupply +from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply from meshtastic.slog import StructuredLogger def onReceive(packet, interface): @@ -1093,6 +1093,16 @@ def common(): meter = None # assume no power meter if args.power_riden: meter = RidenPowerSupply(args.power_riden) + elif args.power_ppk2: + meter = PPK2PowerSupply() + + if meter and args.power_voltage: + v = float(args.power_voltage) + if v < 1.0 or v >5.0: + meshtastic.util.our_exit("Voltage must be between 1.0 and 5.0") + logging.info(f"Setting power supply to {v} volts") + meter.v = v + meter.powerOn() StructuredLogger(client, meter) @@ -1521,6 +1531,11 @@ def initParser(): action="store_true", ) + group.add_argument( + "--power-voltage", + help="Set the specified voltage on the power-supply. Be VERY careful, you can burn things up.", + ) + group.add_argument( "--power-stress", help="Perform power monitor stress testing, to capture a power consumption profile for the device (also requires --power-mon)", diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index d8b4104..c4aa654 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -1,3 +1,5 @@ """Support for logging from power meters/supplies.""" -from .riden import * +from .power_supply import PowerMeter, PowerSupply, PowerError +from .riden import RidenPowerSupply +from .ppk2 import PPK2PowerSupply \ No newline at end of file diff --git a/meshtastic/powermon/power_supply.py b/meshtastic/powermon/power_supply.py new file mode 100644 index 0000000..f87a4b8 --- /dev/null +++ b/meshtastic/powermon/power_supply.py @@ -0,0 +1,49 @@ +"""code logging power consumption of meshtastic devices.""" + +import math +from datetime import datetime + +class PowerError(Exception): + """An exception class for powermon errors""" + def __init__(self, message): + self.message = message + super().__init__(self.message) + + +class PowerMeter: + """Abstract class for power meters.""" + + def __init__(self): + """Initialize the PowerMeter object.""" + self.prevPowerTime = datetime.now() + self.prevWattHour = self._getRawWattHour() + + def getWatts(self) -> float: + """Get the total amount of power that has been consumed since the previous call of this method""" + now = datetime.now() + nowWattHour = self._getRawWattHour() + watts = ( + (nowWattHour - self.prevWattHour) + / (now - self.prevPowerTime).total_seconds() + * 3600 + ) + self.prevPowerTime = now + self.prevWattHour = nowWattHour + return watts + + def _getRawWattHour(self) -> float: + """Get the current watt-hour reading (without any offset correction).""" + return math.nan + + + +class PowerSupply(PowerMeter): + """Abstract class for power supplies.""" + + def __init__(self): + """Initialize the PowerSupply object.""" + super().__init__() + self.v = 3.3 + + def powerOn(self): + """Turn on the power supply (using the voltage set in self.v).""" diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py new file mode 100644 index 0000000..4fe4a88 --- /dev/null +++ b/meshtastic/powermon/ppk2.py @@ -0,0 +1,47 @@ +"""code logging power consumption of meshtastic devices.""" + +import logging +from typing import * + +from ppk2_api import ppk2_api +from .power_supply import PowerSupply, PowerError + + + +class PPK2PowerSupply(PowerSupply): + """Interface for talking with the NRF PPK2 high-resolution micro-power supply. + Power Profiler Kit II is what you should google to find it for purchase. + """ + + def __init__(self, portName: Optional[str] = None): + """Initialize the PowerSupply object. + + portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyACM0". + """ + if not portName: + devs = ppk2_api.PPK2_API.list_devices() + if not devs or len(devs) == 0: + raise PowerError("No PPK2 devices found") + elif len(devs) > 1: + raise PowerError("Multiple PPK2 devices found, please specify the portName") + else: + portName = devs[0] + + self.r = r = ppk2_api.PPK2_MP(portName) # serial port will be different for you + r.get_modifiers() + + logging.info("Connected to PPK2 power supply") + + super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + + def powerOn(self): + """Power on the supply, with reasonable defaults for meshtastic devices.""" + self.r.use_source_meter() # set source meter mode + self.r.set_source_voltage(self.v * 1000) # set source voltage in mV + self.r.toggle_DUT_power("ON") + self.r.start_measuring() # start measuring + + + def _getRawWattHour(self) -> float: + """Get the current watt-hour reading.""" + return 4 # FIXME diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py index 1dd65bc..17d5c02 100644 --- a/meshtastic/powermon/riden.py +++ b/meshtastic/powermon/riden.py @@ -1,52 +1,14 @@ """code logging power consumption of meshtastic devices.""" import logging -import math from datetime import datetime from riden import Riden - -class PowerMeter: - """Abstract class for power meters.""" - - def __init__(self): - """Initialize the PowerMeter object.""" - self.prevPowerTime = datetime.now() - self.prevWattHour = self._getRawWattHour() - - def getWatts(self) -> float: - """Get the total amount of power that has been consumed since the previous call of this method""" - now = datetime.now() - nowWattHour = self._getRawWattHour() - watts = ( - (nowWattHour - self.prevWattHour) - / (now - self.prevPowerTime).total_seconds() - * 3600 - ) - self.prevPowerTime = now - self.prevWattHour = nowWattHour - return watts - - def _getRawWattHour(self) -> float: - """Get the current watt-hour reading (without any offset correction).""" - return math.nan - - - -class PowerSupply(PowerMeter): - """Abstract class for power supplies.""" - - def setMaxCurrent(self, i: float): - """Set the maximum current the supply will provide.""" - - def powerOn(self, v: float): - """Turn on the power supply.""" - - +from .power_supply import PowerSupply class RidenPowerSupply(PowerSupply): - """Interface for talking to programmable bench-top power supplies. - Currently only the Riden supplies are supported (RD6006 tested) + """Interface for talking to Riden programmable bench-top power supplies. + Only RD6006 tested but others should be similar. """ def __init__(self, portName: str = "/dev/ttyUSB0"): @@ -65,9 +27,9 @@ class RidenPowerSupply(PowerSupply): """Set the maximum current the supply will provide.""" self.r.set_i_set(i) - def powerOn(self, v: float): + def powerOn(self): """Power on the supply, with reasonable defaults for meshtastic devices.""" - self.r.set_v_set(v) # my WM1110 devboard header is directly connected to the 3.3V rail + self.r.set_v_set(self.v) # my WM1110 devboard header is directly connected to the 3.3V rail self.r.set_output(1) def _getRawWattHour(self) -> float: diff --git a/poetry.lock b/poetry.lock index 464c3eb..c18bdfb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -928,6 +928,20 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "ppk2-api" +version = "0.9.2" +description = "API for Nordic Semiconductor's Power Profiler Kit II (PPK 2)." +optional = false +python-versions = "*" +files = [ + {file = "ppk2-api-0.9.2.tar.gz", hash = "sha256:e8fb29f782ba6e5bd2e0286079163c495cfffce336f9b149430348c043b25300"}, + {file = "ppk2_api-0.9.2-py3-none-any.whl", hash = "sha256:b7fb02156f87d8430bbce0006876d38c8309ada671fbcd15848173b431198803"}, +] + +[package.dependencies] +pyserial = "*" + [[package]] name = "protobuf" version = "5.27.1" @@ -1794,4 +1808,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "cc81bcd3e4671bde3375f2f08334d6a3b87b38c97f2676d7266cab980082659e" +content-hash = "7719c01f112a7864acdec0a82e7131aa33a646d84459cc0cc6db0eadf94933c7" diff --git a/pyproject.toml b/pyproject.toml index 368c265..c767dd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ packaging = "^24.0" riden = {git = "https://github.com/geeksville/riden.git#1.2.1"} pandas = "^2.2.2" parse = "^1.20.2" +ppk2-api = "^0.9.2" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From 26a672ed587fd2f5f7ca2d0f3225e532c36eb067 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 24 Jun 2024 09:57:46 -0700 Subject: [PATCH 037/248] ppk2 tweaks --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f833f3a..a652316 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -172,7 +172,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-ppk", "--power-voltage", "3.3", "--port", "/dev/ttyACM0", "--noproto", "--seriallog", "stdout"] + "args": ["--power-ppk", "--power-voltage", "0.6", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", From dc8348b99ef60bce8bff3bde46d53d508bd975e6 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 24 Jun 2024 09:59:31 -0700 Subject: [PATCH 038/248] add (optional) poe tool config for easy running of external commands --- pyproject.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c767dd3..525bf97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" readme = "README.md" [tool.poetry.dependencies] -python = "^3.9,<3.13" # 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +python = "^3.9,<3.13" # 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason pyserial = "^3.5" protobuf = ">=5.26.0" dotmap = "^1.3.30" @@ -22,7 +22,7 @@ pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" packaging = "^24.0" -riden = {git = "https://github.com/geeksville/riden.git#1.2.1"} +riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } pandas = "^2.2.2" parse = "^1.20.2" ppk2-api = "^0.9.2" @@ -51,6 +51,12 @@ tunnel = ["pytap2"] meshtastic = "meshtastic.__main__:main" mesh-tunnel = "meshtastic.__main__:tunnelMain [tunnel]" +# "Poe the poet" (optional) provides an easy way of running non python tools inside the poetry virtualenv +# if you would like to use it run "pipx install poe" +# then you can do stuff like "poe code" to run vscode inside this environment +[tool.poe.tasks] +code = "code ." + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" From 43e1f65a75c1a6409a6b6f0eed1f62bf985fd194 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 24 Jun 2024 15:25:14 -0700 Subject: [PATCH 039/248] "python" is deprecated vscode now wants "pydebug" --- .vscode/launch.json | 62 +++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a652316..a9ae9a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "configurations": [ { "name": "meshtastic BLE", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": false, @@ -14,7 +14,7 @@ }, { "name": "meshtastic admin", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -22,7 +22,7 @@ }, { "name": "meshtastic tunnel", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -30,7 +30,7 @@ }, { "name": "meshtastic set chan", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -38,7 +38,7 @@ }, { "name": "meshtastic debug", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -46,7 +46,7 @@ }, { "name": "meshtastic listen", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -54,7 +54,7 @@ }, { "name": "meshtastic debug getPref", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -62,7 +62,7 @@ }, { "name": "meshtastic debug getPref telemetry", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -70,7 +70,7 @@ }, { "name": "meshtastic debug info", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -78,7 +78,7 @@ }, { "name": "meshtastic debug set region", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -86,7 +86,7 @@ }, { "name": "meshtastic debug set bluetooth fixed pin", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -94,7 +94,7 @@ }, { "name": "meshtastic debug get bluetooth fixed pin", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -102,7 +102,7 @@ }, { "name": "meshtastic debug setPref", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -110,7 +110,7 @@ }, { "name": "meshtastic debug setPref telemetry.environment_measurement_enabled", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -118,7 +118,7 @@ }, { "name": "meshtastic debug setPref telemetry.environment_screen_enabled", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -126,7 +126,7 @@ }, { "name": "meshtastic debug setPref telemetry", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -134,7 +134,7 @@ }, { "name": "meshtastic setpref", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -142,7 +142,7 @@ }, { "name": "meshtastic --ch-set", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -151,7 +151,7 @@ { "name": "meshtastic seturl", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -160,23 +160,31 @@ }, { "name": "meshtastic shell", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": false, "args": ["--noproto", "--seriallog", "stdout"] }, { - "name": "meshtastic powermon", - "type": "python", + "name": "meshtastic powermon sim", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-ppk", "--power-voltage", "0.6", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + "args": ["--power-sim", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + }, + { + "name": "meshtastic powermon ppk2", + "type": "debugpy", + "request": "launch", + "module": "meshtastic", + "justMyCode": false, + "args": ["--power-ppk2-meter", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -184,7 +192,7 @@ }, { "name": "meshtastic settime", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -192,7 +200,7 @@ }, { "name": "meshtastic sendtext", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, @@ -200,7 +208,7 @@ }, { "name": "meshtastic showNodes", - "type": "python", + "type": "debugpy", "request": "launch", "module": "meshtastic", "justMyCode": true, From 7ce7d73e89dead1b1be1710f13de73114e79c043 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 24 Jun 2024 15:26:05 -0700 Subject: [PATCH 040/248] Switch from pandas to apache arrow for live data logging (better streaming) --- .vscode/settings.json | 1 + meshtastic/__main__.py | 37 ++++++--- meshtastic/slog/__init__.py | 4 +- meshtastic/slog/arrow.py | 42 ++++++++++ meshtastic/slog/slog.py | 157 ++++++++++++++++++++++-------------- 5 files changed, 170 insertions(+), 71 deletions(-) create mode 100644 meshtastic/slog/arrow.py diff --git a/.vscode/settings.json b/.vscode/settings.json index a1fd574..ba9060a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "boardid", "Meshtastic", "powermon", + "pyarrow", "TORADIO", "Vids" ], diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 323d13e..1287f4f 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -21,8 +21,8 @@ from meshtastic import channel_pb2, config_pb2, portnums_pb2, remote_hardware, B from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply -from meshtastic.slog import StructuredLogger +from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply, SimPowerSupply +from meshtastic.slog import LogSet def onReceive(packet, interface): """Callback invoked when a packet arrives""" @@ -1090,21 +1090,26 @@ def common(): # We assume client is fully connected now onConnected(client) + # Setup power meters meter = None # assume no power meter if args.power_riden: meter = RidenPowerSupply(args.power_riden) - elif args.power_ppk2: + elif args.power_ppk2_supply or args.power_ppk2_meter: meter = PPK2PowerSupply() + meter.setIsSupply(args.power_ppk2_supply) + elif args.power_sim: + meter = SimPowerSupply() if meter and args.power_voltage: v = float(args.power_voltage) - if v < 1.0 or v >5.0: + if v < 0.5 or v >5.0: meshtastic.util.our_exit("Voltage must be between 1.0 and 5.0") logging.info(f"Setting power supply to {v} volts") meter.v = v meter.powerOn() - StructuredLogger(client, meter) + # Setup loggers + LogSet(client, meter) have_tunnel = platform.system() == "Linux" if ( @@ -1520,14 +1525,28 @@ def initParser(): action="store_true", ) - group.add_argument( + power_supply_group = group.add_mutually_exclusive_group() + + power_supply_group.add_argument( "--power-riden", help="Talk to a Riden power-supply. You must specify the device path, i.e. /dev/ttyUSBxxx", ) - group.add_argument( - "--power-ppk2", - help="Talk to a Nordic Power Profiler Kit 2", + power_supply_group.add_argument( + "--power-ppk2-meter", + help="Talk to a Nordic Power Profiler Kit 2 (in meter mode)", + action="store_true", + ) + + power_supply_group.add_argument( + "--power-ppk2-supply", + help="Talk to a Nordic Power Profiler Kit 2 (in supply mode)", + action="store_true", + ) + + power_supply_group.add_argument( + "--power-sim", + help="Use a simulated power meter (for development)", action="store_true", ) diff --git a/meshtastic/slog/__init__.py b/meshtastic/slog/__init__.py index a96ae8e..acd5d21 100644 --- a/meshtastic/slog/__init__.py +++ b/meshtastic/slog/__init__.py @@ -1,3 +1,3 @@ -"""Structured logging framework (see dev docs for more info)""" +"""Structured logging framework (see dev docs for more info).""" -from .slog import StructuredLogger +from .slog import LogSet diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py new file mode 100644 index 0000000..2342c9b --- /dev/null +++ b/meshtastic/slog/arrow.py @@ -0,0 +1,42 @@ +import pyarrow as pa + +chunk_size = 10 # disk writes are batched based on this number of rows + + +class ArrowWriter: + """Writes an arrow file in a streaming fashion""" + + def __init__(self, file_name: str): + """Create a new ArrowWriter object. + + file_name (str): The name of the file to write to. + """ + self.sink = pa.OSFile(file_name, "wb") + self.new_rows: list[dict] = [] + self.schema: pa.Schema | None = None # haven't yet learned the schema + self.writer: pa.RecordBatchFileWriter | None = None + + def close(self): + """Close the stream and writes the file as needed.""" + self._write() + if self.writer: + self.writer.close() + self.sink.close() + + def _write(self): + """Write the new rows to the file.""" + if len(self.new_rows) > 0: + if self.schema is None: + self.schema = pa.Table.from_pylist(self.new_rows).schema + self.writer = pa.ipc.new_stream(self.sink, self.schema) + + self.writer.write_batch(pa.RecordBatch.from_pylist(self.new_rows)) + self.new_rows = [] + + def add_row(self, row_dict: dict): + """Add a row to the arrow file. + We will automatically learn the schema from the first row. But all rows must use that schema. + """ + self.new_rows.append(row_dict) + if len(self.new_rows) >= chunk_size: + self._write() diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index ab47414..0c480e7 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -1,96 +1,104 @@ """code logging power consumption of meshtastic devices.""" +import atexit import logging import re -import atexit -from datetime import datetime +import threading +import time from dataclasses import dataclass +from datetime import datetime import parse -import pandas as pd -from pubsub import pub # type: ignore[import-untyped] +from pubsub import pub # type: ignore[import-untyped] from meshtastic.mesh_interface import MeshInterface from meshtastic.powermon import PowerMeter +from .arrow import ArrowWriter + @dataclass(init=False) class LogDef: """Log definition.""" - code: str # i.e. PM or B or whatever... see meshtastic slog documentation - format: str # A format string that can be used to parse the arguments + + code: str # i.e. PM or B or whatever... see meshtastic slog documentation + format: str # A format string that can be used to parse the arguments def __init__(self, code: str, fmt: str) -> None: """Initialize the LogDef object. - code (str): The code. - format (str): The format. + code (str): The code. + format (str): The format. """ self.code = code self.format = parse.compile(fmt) + """A dictionary mapping from logdef code to logdef""" -log_defs = {d.code: d for d in [ - LogDef("B", "{boardid:d},{version}"), - LogDef("PM", "{bitmask:d},{reason}") - ]} +log_defs = { + d.code: d + for d in [ + LogDef("B", "{boardid:d},{version}"), + LogDef("PM", "{bitmask:d},{reason}"), + ] +} log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") +class PowerLogger: + """Logs current watts reading periodically using PowerMeter and ArrowWriter.""" + + def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.2) -> None: + """Initialize the PowerLogger object.""" + self.pMeter = pMeter + self.writer = ArrowWriter(file_path) + self.interval = interval + self.is_logging = True + self.thread = threading.Thread(target=self._logging_thread, name="PowerLogger") + self.thread.start() + + def _logging_thread(self) -> None: + """Background thread for logging the current watts reading.""" + while self.is_logging: + watts = self.pMeter.getWatts() + d = {"time": datetime.now(), "watts": watts} + self.writer.add_row(d) + time.sleep(self.interval) + + def close(self) -> None: + """Close the PowerLogger and stop logging.""" + if self.is_logging: + self.is_logging = False + self.thread.join() + self.writer.close() + +# FIXME move these defs somewhere else +TOPIC_MESHTASTIC_LOG_LINE = "meshtastic.log.line" + class StructuredLogger: """Sniffs device logs for structured log messages, extracts those into pandas/CSV format.""" - def __init__(self, client: MeshInterface, pMeter: PowerMeter = None) -> None: + def __init__(self, client: MeshInterface, file_path: str) -> None: """Initialize the PowerMonClient object. - power (PowerSupply): The power supply object. - client (MeshInterface): The MeshInterface object to monitor. + power (PowerSupply): The power supply object. + client (MeshInterface): The MeshInterface object to monitor. """ self.client = client - self.pMeter = pMeter - self.columns = ["time", "power"] - self.rawData = pd.DataFrame(columns=self.columns) # use time as the index - # self.rawData.set_index("time", inplace=True) + self.writer = ArrowWriter(file_path) + self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) - # for efficiency reasons we keep new data in a list - only adding to rawData when needed - self.newData: list[dict] = [] + def close(self) -> None: + """Stop logging.""" + pub.unsubscribe(self.listener, TOPIC_MESHTASTIC_LOG_LINE) + self.writer.close() - atexit.register(self._exitHandler) - pub.subscribe(self._onLogMessage, "meshtastic.log.line") - - def getRawData(self) -> pd.DataFrame: - """Get the raw data. - - Returns - ------- - pd.DataFrame: The raw data. - """ - - df = pd.DataFrame(self.newData) - - # We prefer some columns to be integers - intcols = [ "bitmask" ] - for c in intcols: - if c in df: - df[c] = df[c].astype('Int64') - - # df.set_index("time") - # Add new data, creating new columns as needed (an outer join) - self.rawData = pd.concat([self.rawData, df], axis=0, ignore_index=True) - self.newData = [] - - return self.rawData - - def _exitHandler(self) -> None: - """Exit handler.""" - fn = "/tmp/powermon.slog" # Find a better place - logging.info(f"Storing slog in {fn}") - self.getRawData().to_csv(fn) - - def _onLogMessage(self, line: str, interface: MeshInterface) -> None: # pylint: disable=unused-argument + def _onLogMessage( + self, line: str, interface: MeshInterface + ) -> None: # pylint: disable=unused-argument """Handle log messages. - line (str): the line of log output + line (str): the line of log output """ m = log_regex.match(line) if m: @@ -101,15 +109,44 @@ class StructuredLogger: logging.debug(f"SLog {src}, reason: {args}") d = log_defs.get(src) if d: - r = d.format.parse(args) # get the values with the correct types + r = d.format.parse(args) # get the values with the correct types if r: di = r.named di["time"] = datetime.now() - if self.pMeter: # if we have a power meter include a fresh power reading - di["power"] = self.pMeter.getWatts() - self.newData.append(di) - self.getRawData() + self.writer.add_row(di) else: logging.warning(f"Failed to parse slog {line} with {d.format}") else: logging.warning(f"Unknown Structured Log: {line}") + + +class LogSet: + """A complete set of meshtastic log/metadata for a particular run.""" + + def __init__(self, client: MeshInterface, power_meter: PowerMeter = None) -> None: + """Initialize the PowerMonClient object. + + power (PowerSupply): The power supply object. + client (MeshInterface): The MeshInterface object to monitor. + """ + self.dir_name = "/tmp" # FIXME + + self.slog_logger = StructuredLogger(client, f"{self.dir_name}/slog.arrow") + if power_meter: + self.power_logger = PowerLogger(power_meter, f"{self.dir_name}/power.arrow") + else: + self.power_logger = None + + atexit.register(self._exitHandler) + + def close(self) -> None: + """Close the log set.""" + + logging.info(f"Storing slog in {self.dir_name}") + self.slog_logger.close() + if self.power_logger: + self.power_logger.close() + + def _exitHandler(self) -> None: + """Exit handler.""" + self.close() From 91066f6aed48d191e670556ca987bf1079f02e1d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 08:57:37 -0700 Subject: [PATCH 041/248] add powermon_sim support --- meshtastic/powermon/__init__.py | 3 ++- meshtastic/powermon/power_supply.py | 7 +++--- meshtastic/powermon/ppk2.py | 33 +++++++++++++++++++++-------- meshtastic/powermon/riden.py | 10 ++++++--- meshtastic/powermon/sim.py | 17 +++++++++++++++ pyproject.toml | 3 ++- 6 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 meshtastic/powermon/sim.py diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index c4aa654..9db5544 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -2,4 +2,5 @@ from .power_supply import PowerMeter, PowerSupply, PowerError from .riden import RidenPowerSupply -from .ppk2 import PPK2PowerSupply \ No newline at end of file +from .ppk2 import PPK2PowerSupply +from .sim import SimPowerSupply \ No newline at end of file diff --git a/meshtastic/powermon/power_supply.py b/meshtastic/powermon/power_supply.py index f87a4b8..18463a7 100644 --- a/meshtastic/powermon/power_supply.py +++ b/meshtastic/powermon/power_supply.py @@ -3,8 +3,10 @@ import math from datetime import datetime + class PowerError(Exception): """An exception class for powermon errors""" + def __init__(self, message): self.message = message super().__init__(self.message) @@ -19,7 +21,7 @@ class PowerMeter: self.prevWattHour = self._getRawWattHour() def getWatts(self) -> float: - """Get the total amount of power that has been consumed since the previous call of this method""" + """Get the total amount of power that is currently being consumed.""" now = datetime.now() nowWattHour = self._getRawWattHour() watts = ( @@ -36,14 +38,13 @@ class PowerMeter: return math.nan - class PowerSupply(PowerMeter): """Abstract class for power supplies.""" def __init__(self): """Initialize the PowerSupply object.""" super().__init__() - self.v = 3.3 + self.v = 0.0 def powerOn(self): """Turn on the power supply (using the voltage set in self.v).""" diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 4fe4a88..db90635 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -4,8 +4,8 @@ import logging from typing import * from ppk2_api import ppk2_api -from .power_supply import PowerSupply, PowerError +from .power_supply import PowerError, PowerSupply class PPK2PowerSupply(PowerSupply): @@ -16,32 +16,47 @@ class PPK2PowerSupply(PowerSupply): def __init__(self, portName: Optional[str] = None): """Initialize the PowerSupply object. - portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyACM0". + portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyACM0". """ if not portName: devs = ppk2_api.PPK2_API.list_devices() if not devs or len(devs) == 0: raise PowerError("No PPK2 devices found") elif len(devs) > 1: - raise PowerError("Multiple PPK2 devices found, please specify the portName") + raise PowerError( + "Multiple PPK2 devices found, please specify the portName" + ) else: portName = devs[0] self.r = r = ppk2_api.PPK2_MP(portName) # serial port will be different for you r.get_modifiers() + self.r.start_measuring() # start measuring logging.info("Connected to PPK2 power supply") - super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + + def setIsSupply(self, s: bool): + """If in supply mode we will provide power ourself, otherwise we are just an amp meter.""" + if ( + not s + ): # min power outpuf of PPK2. If less than this assume we want just meter mode. + self.r.use_ampere_meter() + else: + self.r.set_source_voltage( + int(self.v * 1000) + ) # set source voltage in mV BEFORE setting source mode + self.r.use_source_meter() # set source meter mode def powerOn(self): - """Power on the supply, with reasonable defaults for meshtastic devices.""" - self.r.use_source_meter() # set source meter mode - self.r.set_source_voltage(self.v * 1000) # set source voltage in mV + """Power on the supply.""" self.r.toggle_DUT_power("ON") - self.r.start_measuring() # start measuring + def powerOff(self): + """Power off the supply.""" + self.r.toggle_DUT_power("OFF") def _getRawWattHour(self) -> float: """Get the current watt-hour reading.""" - return 4 # FIXME + return 4 # FIXME diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py index 17d5c02..c425855 100644 --- a/meshtastic/powermon/riden.py +++ b/meshtastic/powermon/riden.py @@ -4,8 +4,10 @@ import logging from datetime import datetime from riden import Riden + from .power_supply import PowerSupply + class RidenPowerSupply(PowerSupply): """Interface for talking to Riden programmable bench-top power supplies. Only RD6006 tested but others should be similar. @@ -14,14 +16,14 @@ class RidenPowerSupply(PowerSupply): def __init__(self, portName: str = "/dev/ttyUSB0"): """Initialize the RidenPowerSupply object. - portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0". + portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0". """ self.r = r = Riden(port=portName, baudrate=115200, address=1) logging.info( f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." ) r.set_date_time(datetime.now()) - super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works def setMaxCurrent(self, i: float): """Set the maximum current the supply will provide.""" @@ -29,7 +31,9 @@ class RidenPowerSupply(PowerSupply): def powerOn(self): """Power on the supply, with reasonable defaults for meshtastic devices.""" - self.r.set_v_set(self.v) # my WM1110 devboard header is directly connected to the 3.3V rail + self.r.set_v_set( + self.v + ) # my WM1110 devboard header is directly connected to the 3.3V rail self.r.set_output(1) def _getRawWattHour(self) -> float: diff --git a/meshtastic/powermon/sim.py b/meshtastic/powermon/sim.py new file mode 100644 index 0000000..9b6ea12 --- /dev/null +++ b/meshtastic/powermon/sim.py @@ -0,0 +1,17 @@ +"""code logging power consumption of meshtastic devices.""" + +import math +import time +from typing import * + +from .power_supply import PowerError, PowerSupply + + +class SimPowerSupply(PowerSupply): + """A simulated power supply for testing.""" + + def getWatts(self) -> float: + """Get the total amount of power that is currently being consumed.""" + + # Sim a 20mW load that varies sinusoidally + return (20 + 5 * math.sin(time.time())) / 1000 diff --git a/pyproject.toml b/pyproject.toml index 525bf97..3eee1fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,9 +23,10 @@ pypubsub = "^4.0.3" bleak = "^0.21.1" packaging = "^24.0" riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } -pandas = "^2.2.2" parse = "^1.20.2" ppk2-api = "^0.9.2" +pyarrow = "^16.1.0" +pyarrow-stubs = "^10.0.1.7" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From 9cdfde47ec1843aae408be4be1398b5e0a2d96a0 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:02:07 -0700 Subject: [PATCH 042/248] store slogs in correct default directory (OS dependent) --- .vscode/launch.json | 4 +- meshtastic/__main__.py | 9 +- meshtastic/powermon/power_supply.py | 4 +- meshtastic/powermon/ppk2.py | 4 +- meshtastic/powermon/sim.py | 2 +- meshtastic/slog/arrow.py | 2 +- meshtastic/slog/slog.py | 55 ++++++--- poetry.lock | 180 +++++++++------------------- pyproject.toml | 1 + 9 files changed, 112 insertions(+), 149 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a9ae9a2..5add7d9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -172,7 +172,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-sim", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + "args": ["--slog-out", "default", "--power-sim", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic powermon ppk2", @@ -180,7 +180,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--power-ppk2-meter", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 1287f4f..793f2d7 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1108,8 +1108,9 @@ def common(): meter.v = v meter.powerOn() - # Setup loggers - LogSet(client, meter) + if args.slog_out: + # Setup loggers + LogSet(client, args.slog_out if args.slog_out != 'default' else None, meter) have_tunnel = platform.system() == "Linux" if ( @@ -1561,6 +1562,10 @@ def initParser(): action="store_true", ) + group.add_argument( + "--slog-out", + help="A directory to store structured logging to, or 'default' for automatically selected.", + ) group.add_argument( "--ble-scan", help="Scan for Meshtastic BLE devices", diff --git a/meshtastic/powermon/power_supply.py b/meshtastic/powermon/power_supply.py index 18463a7..cb4d044 100644 --- a/meshtastic/powermon/power_supply.py +++ b/meshtastic/powermon/power_supply.py @@ -20,8 +20,8 @@ class PowerMeter: self.prevPowerTime = datetime.now() self.prevWattHour = self._getRawWattHour() - def getWatts(self) -> float: - """Get the total amount of power that is currently being consumed.""" + def getAverageWatts(self) -> float: + """Get watts consumed since last call to this method.""" now = datetime.now() nowWattHour = self._getRawWattHour() watts = ( diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index db90635..79f87ff 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -57,6 +57,4 @@ class PPK2PowerSupply(PowerSupply): """Power off the supply.""" self.r.toggle_DUT_power("OFF") - def _getRawWattHour(self) -> float: - """Get the current watt-hour reading.""" - return 4 # FIXME + diff --git a/meshtastic/powermon/sim.py b/meshtastic/powermon/sim.py index 9b6ea12..c66c5b3 100644 --- a/meshtastic/powermon/sim.py +++ b/meshtastic/powermon/sim.py @@ -10,7 +10,7 @@ from .power_supply import PowerError, PowerSupply class SimPowerSupply(PowerSupply): """A simulated power supply for testing.""" - def getWatts(self) -> float: + def getAverageWatts(self) -> float: """Get the total amount of power that is currently being consumed.""" # Sim a 20mW load that varies sinusoidally diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 2342c9b..157f581 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -1,6 +1,6 @@ import pyarrow as pa -chunk_size = 10 # disk writes are batched based on this number of rows +chunk_size = 1000 # disk writes are batched based on this number of rows class ArrowWriter: diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 0c480e7..d2cc41f 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -5,16 +5,20 @@ import logging import re import threading import time +import os from dataclasses import dataclass from datetime import datetime +from typing import Optional import parse +import platformdirs from pubsub import pub # type: ignore[import-untyped] from meshtastic.mesh_interface import MeshInterface from meshtastic.powermon import PowerMeter from .arrow import ArrowWriter +import os @dataclass(init=False) @@ -54,13 +58,13 @@ class PowerLogger: self.writer = ArrowWriter(file_path) self.interval = interval self.is_logging = True - self.thread = threading.Thread(target=self._logging_thread, name="PowerLogger") + self.thread = threading.Thread(target=self._logging_thread, name="PowerLogger", daemon=True) self.thread.start() def _logging_thread(self) -> None: """Background thread for logging the current watts reading.""" while self.is_logging: - watts = self.pMeter.getWatts() + watts = self.pMeter.getAverageWatts() d = {"time": datetime.now(), "watts": watts} self.writer.add_row(d) time.sleep(self.interval) @@ -72,26 +76,33 @@ class PowerLogger: self.thread.join() self.writer.close() + # FIXME move these defs somewhere else TOPIC_MESHTASTIC_LOG_LINE = "meshtastic.log.line" + class StructuredLogger: - """Sniffs device logs for structured log messages, extracts those into pandas/CSV format.""" + """Sniffs device logs for structured log messages, extracts those into apache arrow format. + Also writes the raw log messages to raw.txt""" - def __init__(self, client: MeshInterface, file_path: str) -> None: - """Initialize the PowerMonClient object. + def __init__(self, client: MeshInterface, dir_path: str) -> None: + """Initialize the StructuredLogger object. - power (PowerSupply): The power supply object. client (MeshInterface): The MeshInterface object to monitor. """ self.client = client - self.writer = ArrowWriter(file_path) + self.writer = ArrowWriter(f"{dir_path}/slog.arrow") + # trunk-ignore(pylint/R1732) + self.raw_file = open( + f"{dir_path}/raw.txt", "w", encoding="utf8" + ) self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) def close(self) -> None: """Stop logging.""" pub.unsubscribe(self.listener, TOPIC_MESHTASTIC_LOG_LINE) self.writer.close() + self.raw_file.close() # Close the raw.txt file def _onLogMessage( self, line: str, interface: MeshInterface @@ -104,7 +115,6 @@ class StructuredLogger: if m: src = m.group(1) args = m.group(2) - args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match logging.debug(f"SLog {src}, reason: {args}") d = log_defs.get(src) @@ -118,35 +128,46 @@ class StructuredLogger: logging.warning(f"Failed to parse slog {line} with {d.format}") else: logging.warning(f"Unknown Structured Log: {line}") + self.raw_file.write(line + "\n") # Write the raw log class LogSet: """A complete set of meshtastic log/metadata for a particular run.""" - def __init__(self, client: MeshInterface, power_meter: PowerMeter = None) -> None: + def __init__( + self, + client: MeshInterface, + dir_name: Optional[str] = None, + power_meter: PowerMeter = None, + ) -> None: """Initialize the PowerMonClient object. power (PowerSupply): The power supply object. client (MeshInterface): The MeshInterface object to monitor. """ - self.dir_name = "/tmp" # FIXME - self.slog_logger = StructuredLogger(client, f"{self.dir_name}/slog.arrow") + if not dir_name: + app_name = "meshtastic" + app_author = "meshtastic" + app_dir = platformdirs.user_data_dir(app_name, app_author) + dir_name = f"{app_dir}/slogs/{datetime.now().strftime('%Y%m%d-%H%M%S')}" + os.makedirs(dir_name, exist_ok=True) + self.dir_name = dir_name + + logging.info(f"Writing slogs to {dir_name}") + + self.slog_logger = StructuredLogger(client, self.dir_name) if power_meter: self.power_logger = PowerLogger(power_meter, f"{self.dir_name}/power.arrow") else: self.power_logger = None - atexit.register(self._exitHandler) + atexit.register(self.close) def close(self) -> None: """Close the log set.""" - logging.info(f"Storing slog in {self.dir_name}") + logging.info(f"Closing slogs in {self.dir_name}") self.slog_logger.close() if self.power_logger: self.power_logger.close() - - def _exitHandler(self) -> None: - """Exit handler.""" - self.close() diff --git a/poetry.lock b/poetry.lock index c18bdfb..b872b40 100644 --- a/poetry.lock +++ b/poetry.lock @@ -773,79 +773,6 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] -[[package]] -name = "pandas" -version = "2.2.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, - {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, - {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, - {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, - {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, - {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, - {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - [[package]] name = "parse" version = "1.20.2" @@ -973,6 +900,64 @@ files = [ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +[[package]] +name = "pyarrow" +version = "16.1.0" +description = "Python library for Apache Arrow" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyarrow-16.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:17e23b9a65a70cc733d8b738baa6ad3722298fa0c81d88f63ff94bf25eaa77b9"}, + {file = "pyarrow-16.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4740cc41e2ba5d641071d0ab5e9ef9b5e6e8c7611351a5cb7c1d175eaf43674a"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98100e0268d04e0eec47b73f20b39c45b4006f3c4233719c3848aa27a03c1aef"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68f409e7b283c085f2da014f9ef81e885d90dcd733bd648cfba3ef265961848"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a8914cd176f448e09746037b0c6b3a9d7688cef451ec5735094055116857580c"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:48be160782c0556156d91adbdd5a4a7e719f8d407cb46ae3bb4eaee09b3111bd"}, + {file = "pyarrow-16.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9cf389d444b0f41d9fe1444b70650fea31e9d52cfcb5f818b7888b91b586efff"}, + {file = "pyarrow-16.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d0ebea336b535b37eee9eee31761813086d33ed06de9ab6fc6aaa0bace7b250c"}, + {file = "pyarrow-16.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e73cfc4a99e796727919c5541c65bb88b973377501e39b9842ea71401ca6c1c"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9251264247ecfe93e5f5a0cd43b8ae834f1e61d1abca22da55b20c788417f6"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf5aace92d520d3d2a20031d8b0ec27b4395cab9f74e07cc95edf42a5cc0147"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:25233642583bf658f629eb230b9bb79d9af4d9f9229890b3c878699c82f7d11e"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a33a64576fddfbec0a44112eaf844c20853647ca833e9a647bfae0582b2ff94b"}, + {file = "pyarrow-16.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:185d121b50836379fe012753cf15c4ba9638bda9645183ab36246923875f8d1b"}, + {file = "pyarrow-16.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:2e51ca1d6ed7f2e9d5c3c83decf27b0d17bb207a7dea986e8dc3e24f80ff7d6f"}, + {file = "pyarrow-16.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b04707f1979815f5e49824ce52d1dceb46e2f12909a48a6a753fe7cafbc44a0c"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d32000693deff8dc5df444b032b5985a48592c0697cb6e3071a5d59888714e2"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8785bb10d5d6fd5e15d718ee1d1f914fe768bf8b4d1e5e9bf253de8a26cb1628"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e1369af39587b794873b8a307cc6623a3b1194e69399af0efd05bb202195a5a7"}, + {file = "pyarrow-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:febde33305f1498f6df85e8020bca496d0e9ebf2093bab9e0f65e2b4ae2b3444"}, + {file = "pyarrow-16.1.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b5f5705ab977947a43ac83b52ade3b881eb6e95fcc02d76f501d549a210ba77f"}, + {file = "pyarrow-16.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0d27bf89dfc2576f6206e9cd6cf7a107c9c06dc13d53bbc25b0bd4556f19cf5f"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d07de3ee730647a600037bc1d7b7994067ed64d0eba797ac74b2bc77384f4c2"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbef391b63f708e103df99fbaa3acf9f671d77a183a07546ba2f2c297b361e83"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19741c4dbbbc986d38856ee7ddfdd6a00fc3b0fc2d928795b95410d38bb97d15"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f2c5fb249caa17b94e2b9278b36a05ce03d3180e6da0c4c3b3ce5b2788f30eed"}, + {file = "pyarrow-16.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:e6b6d3cd35fbb93b70ade1336022cc1147b95ec6af7d36906ca7fe432eb09710"}, + {file = "pyarrow-16.1.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:18da9b76a36a954665ccca8aa6bd9f46c1145f79c0bb8f4f244f5f8e799bca55"}, + {file = "pyarrow-16.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:99f7549779b6e434467d2aa43ab2b7224dd9e41bdde486020bae198978c9e05e"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f07fdffe4fd5b15f5ec15c8b64584868d063bc22b86b46c9695624ca3505b7b4"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddfe389a08ea374972bd4065d5f25d14e36b43ebc22fc75f7b951f24378bf0b5"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b20bd67c94b3a2ea0a749d2a5712fc845a69cb5d52e78e6449bbd295611f3aa"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ba8ac20693c0bb0bf4b238751d4409e62852004a8cf031c73b0e0962b03e45e3"}, + {file = "pyarrow-16.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:31a1851751433d89a986616015841977e0a188662fcffd1a5677453f1df2de0a"}, + {file = "pyarrow-16.1.0.tar.gz", hash = "sha256:15fbb22ea96d11f0b5768504a3f961edab25eaf4197c341720c4a387f6c60315"}, +] + +[package.dependencies] +numpy = ">=1.16.6" + +[[package]] +name = "pyarrow-stubs" +version = "10.0.1.7" +description = "Type annotations for pyarrow" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "pyarrow_stubs-10.0.1.7-py3-none-any.whl", hash = "sha256:cccc7a46eddeea4e3cb85330eb8972c116a615da6188b8ae1f7a44cb724b21ac"}, +] + [[package]] name = "pycodestyle" version = "2.12.0" @@ -1242,31 +1227,6 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pywin32-ctypes" version = "0.2.2" @@ -1393,17 +1353,6 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1530,17 +1479,6 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -[[package]] -name = "tzdata" -version = "2024.1" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, -] - [[package]] name = "urllib3" version = "2.2.2" @@ -1808,4 +1746,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "7719c01f112a7864acdec0a82e7131aa33a646d84459cc0cc6db0eadf94933c7" +content-hash = "b42cdca565b7cbe0ba16405328144b06cd8394d64cb41dac4def2c68d1f1e4b4" diff --git a/pyproject.toml b/pyproject.toml index 3eee1fe..ca9070f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ parse = "^1.20.2" ppk2-api = "^0.9.2" pyarrow = "^16.1.0" pyarrow-stubs = "^10.0.1.7" +platformdirs = "^4.2.2" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From c6561713dbcff538c6d857e936dd1f165c43d2ef Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:09:08 -0700 Subject: [PATCH 043/248] don't let daemon keep process alive --- meshtastic/stream_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index 18d6e9f..55c1691 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -42,7 +42,7 @@ class StreamInterface(MeshInterface): self.cur_log_line = "" # FIXME, figure out why daemon=True causes reader thread to exit too early - self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True) + self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True, name="stream reader") MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes) From 07fc991f4e2738ab1216976fbc55855eda86a876 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 10:39:44 -0700 Subject: [PATCH 044/248] clean up slog closing --- meshtastic/__main__.py | 6 +++++- meshtastic/slog/slog.py | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 793f2d7..bbc4bb7 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1108,9 +1108,10 @@ def common(): meter.v = v meter.powerOn() + log_set = None if args.slog_out: # Setup loggers - LogSet(client, args.slog_out if args.slog_out != 'default' else None, meter) + log_set = LogSet(client, args.slog_out if args.slog_out != 'default' else None, meter) have_tunnel = platform.system() == "Linux" if ( @@ -1122,6 +1123,9 @@ def common(): except KeyboardInterrupt: logging.info("Exiting due to keyboard interrupt") + if log_set: + log_set.close() + # don't call exit, background threads might be running still # sys.exit(0) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index d2cc41f..9bee592 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -162,12 +162,17 @@ class LogSet: else: self.power_logger = None + # Store a lambda so we can find it again to unregister + self.atexit_handler = lambda: self.close() atexit.register(self.close) def close(self) -> None: """Close the log set.""" - logging.info(f"Closing slogs in {self.dir_name}") - self.slog_logger.close() - if self.power_logger: - self.power_logger.close() + if self.slog_logger: + logging.info(f"Closing slogs in {self.dir_name}") + atexit.unregister(self.atexit_handler) # docs say it will silently ignore if not found + self.slog_logger.close() + if self.power_logger: + self.power_logger.close() + self.slog_logger = None From 1b045bec884662d8628930d68b0a48ec4857bbe6 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:02:24 -0700 Subject: [PATCH 045/248] fix linter warnings --- meshtastic/powermon/__init__.py | 6 +++--- meshtastic/powermon/ppk2.py | 4 +--- meshtastic/powermon/sim.py | 3 +-- meshtastic/slog/arrow.py | 2 ++ meshtastic/slog/slog.py | 17 +++++++++-------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index 9db5544..a8f578f 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -1,6 +1,6 @@ """Support for logging from power meters/supplies.""" -from .power_supply import PowerMeter, PowerSupply, PowerError -from .riden import RidenPowerSupply +from .power_supply import PowerError, PowerMeter, PowerSupply from .ppk2 import PPK2PowerSupply -from .sim import SimPowerSupply \ No newline at end of file +from .riden import RidenPowerSupply +from .sim import SimPowerSupply diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 79f87ff..3f8c67f 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -1,7 +1,7 @@ """code logging power consumption of meshtastic devices.""" import logging -from typing import * +from typing import Optional from ppk2_api import ppk2_api @@ -56,5 +56,3 @@ class PPK2PowerSupply(PowerSupply): def powerOff(self): """Power off the supply.""" self.r.toggle_DUT_power("OFF") - - diff --git a/meshtastic/powermon/sim.py b/meshtastic/powermon/sim.py index c66c5b3..e7e8484 100644 --- a/meshtastic/powermon/sim.py +++ b/meshtastic/powermon/sim.py @@ -2,9 +2,8 @@ import math import time -from typing import * -from .power_supply import PowerError, PowerSupply +from .power_supply import PowerSupply class SimPowerSupply(PowerSupply): diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 157f581..71703c1 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -1,3 +1,5 @@ +"""Utilities for Apache Arrow serialization.""" + import pyarrow as pa chunk_size = 1000 # disk writes are batched based on this number of rows diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 9bee592..720886a 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -2,10 +2,10 @@ import atexit import logging +import os import re import threading import time -import os from dataclasses import dataclass from datetime import datetime from typing import Optional @@ -18,7 +18,6 @@ from meshtastic.mesh_interface import MeshInterface from meshtastic.powermon import PowerMeter from .arrow import ArrowWriter -import os @dataclass(init=False) @@ -58,7 +57,9 @@ class PowerLogger: self.writer = ArrowWriter(file_path) self.interval = interval self.is_logging = True - self.thread = threading.Thread(target=self._logging_thread, name="PowerLogger", daemon=True) + self.thread = threading.Thread( + target=self._logging_thread, name="PowerLogger", daemon=True + ) self.thread.start() def _logging_thread(self) -> None: @@ -92,10 +93,9 @@ class StructuredLogger: """ self.client = client self.writer = ArrowWriter(f"{dir_path}/slog.arrow") - # trunk-ignore(pylint/R1732) self.raw_file = open( f"{dir_path}/raw.txt", "w", encoding="utf8" - ) + ) # pylint: disable=consider-using-with self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) def close(self) -> None: @@ -163,15 +163,16 @@ class LogSet: self.power_logger = None # Store a lambda so we can find it again to unregister - self.atexit_handler = lambda: self.close() - atexit.register(self.close) + self.atexit_handler = lambda: self.close() # pylint: disable=unnecessary-lambda def close(self) -> None: """Close the log set.""" if self.slog_logger: logging.info(f"Closing slogs in {self.dir_name}") - atexit.unregister(self.atexit_handler) # docs say it will silently ignore if not found + atexit.unregister( + self.atexit_handler + ) # docs say it will silently ignore if not found self.slog_logger.close() if self.power_logger: self.power_logger.close() From 8d94458e559368f4813568837cc84169f1114852 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:02:58 -0700 Subject: [PATCH 046/248] flake8 has different settings than trunk, don't confict in vscode --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ba9060a..f393e65 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,6 @@ "TORADIO", "Vids" ], - "python.pythonPath": "/usr/bin/python3" + "python.pythonPath": "/usr/bin/python3", + "flake8.enabled" : false // we are using trunk for formatting/linting rules, don't yell at us about line length } \ No newline at end of file From 9b61f11c88bc3ab8c422a1dbb414e29713943391 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:08:35 -0700 Subject: [PATCH 047/248] temporarily suppress warning about main.py being too long --- meshtastic/__main__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index bbc4bb7..0014ab3 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1,7 +1,10 @@ -#!python3 """ Main Meshtastic """ +# 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=too-many-lines + import argparse import logging import os From 220241448f6456b041b1d9332b477c7c75acdac7 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:08:47 -0700 Subject: [PATCH 048/248] more fighting with trunk --- meshtastic/slog/slog.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 720886a..1eac5e7 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -93,9 +93,9 @@ class StructuredLogger: """ self.client = client self.writer = ArrowWriter(f"{dir_path}/slog.arrow") - self.raw_file = open( + self.raw_file = open( # pylint: disable=consider-using-with f"{dir_path}/raw.txt", "w", encoding="utf8" - ) # pylint: disable=consider-using-with + ) self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) def close(self) -> None: @@ -105,8 +105,8 @@ class StructuredLogger: self.raw_file.close() # Close the raw.txt file def _onLogMessage( - self, line: str, interface: MeshInterface - ) -> None: # pylint: disable=unused-argument + self, line: str, interface: MeshInterface # pylint: disable=unused-argument + ) -> None: """Handle log messages. line (str): the line of log output From 402622f4271dd26447679c29eff866568cb0a644 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:25:07 -0700 Subject: [PATCH 049/248] fix type warnings --- meshtastic/powermon/ppk2.py | 4 ++-- meshtastic/slog/arrow.py | 2 +- meshtastic/slog/slog.py | 17 +++++++++-------- poetry.lock | 2 +- pyproject.toml | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 3f8c67f..bec4c1d 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -1,9 +1,9 @@ -"""code logging power consumption of meshtastic devices.""" +"""Classes for logging power consumption of meshtastic devices.""" import logging from typing import Optional -from ppk2_api import ppk2_api +from ppk2_api import ppk2_api # type: ignore[import-untyped] from .power_supply import PowerError, PowerSupply diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 71703c1..225d3ce 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -13,7 +13,7 @@ class ArrowWriter: file_name (str): The name of the file to write to. """ - self.sink = pa.OSFile(file_name, "wb") + self.sink = pa.OSFile(file_name, "wb") # type: ignore self.new_rows: list[dict] = [] self.schema: pa.Schema | None = None # haven't yet learned the schema self.writer: pa.RecordBatchFileWriter | None = None diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 1eac5e7..0dd0690 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -10,7 +10,7 @@ from dataclasses import dataclass from datetime import datetime from typing import Optional -import parse +import parse # type: ignore[import-untyped] import platformdirs from pubsub import pub # type: ignore[import-untyped] @@ -25,7 +25,7 @@ class LogDef: """Log definition.""" code: str # i.e. PM or B or whatever... see meshtastic slog documentation - format: str # A format string that can be used to parse the arguments + format: parse.Parser # A format string that can be used to parse the arguments def __init__(self, code: str, fmt: str) -> None: """Initialize the LogDef object. @@ -138,7 +138,7 @@ class LogSet: self, client: MeshInterface, dir_name: Optional[str] = None, - power_meter: PowerMeter = None, + power_meter: Optional[PowerMeter] = None, ) -> None: """Initialize the PowerMonClient object. @@ -156,11 +156,12 @@ class LogSet: logging.info(f"Writing slogs to {dir_name}") - self.slog_logger = StructuredLogger(client, self.dir_name) - if power_meter: - self.power_logger = PowerLogger(power_meter, f"{self.dir_name}/power.arrow") - else: - self.power_logger = None + self.slog_logger: Optional[StructuredLogger] = StructuredLogger(client, self.dir_name) + self.power_logger: Optional[PowerLogger] = ( + None + if not power_meter + else PowerLogger(power_meter, f"{self.dir_name}/power.arrow") + ) # Store a lambda so we can find it again to unregister self.atexit_handler = lambda: self.close() # pylint: disable=unnecessary-lambda diff --git a/poetry.lock b/poetry.lock index b872b40..af2ca49 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1746,4 +1746,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "b42cdca565b7cbe0ba16405328144b06cd8394d64cb41dac4def2c68d1f1e4b4" +content-hash = "ad12848e1311886733ea3205795e49e405c2012e9dcff2df6e926ef1cd1dd4b0" diff --git a/pyproject.toml b/pyproject.toml index ca9070f..e0b99b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } parse = "^1.20.2" ppk2-api = "^0.9.2" pyarrow = "^16.1.0" -pyarrow-stubs = "^10.0.1.7" platformdirs = "^4.2.2" [tool.poetry.group.dev.dependencies] @@ -45,6 +44,7 @@ types-tabulate = "^0.9.0.20240106" types-requests = "^2.31.0.20240406" types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" +pyarrow-stubs = "^10.0.1.7" [tool.poetry.extras] tunnel = ["pytap2"] From b30cde979caea2bb899a222bffe2b5a3c36a2b1d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 11:31:02 -0700 Subject: [PATCH 050/248] fix bitrot in an old sanity test - use correct namespace --- tests/hello_world.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/hello_world.py b/tests/hello_world.py index 8fd8f79..8c25f8f 100644 --- a/tests/hello_world.py +++ b/tests/hello_world.py @@ -1,9 +1,7 @@ -import time - -import meshtastic +import meshtastic.serial_interface interface = ( - meshtastic.SerialInterface() + meshtastic.serial_interface.SerialInterface() ) # By default will try to find a meshtastic device, otherwise provide a device path like /dev/ttyUSB0 interface.sendText("hello mesh") interface.close() From d448ea5767fde975db048391febfd8c9fddbbaaf Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 12:03:35 -0700 Subject: [PATCH 051/248] keep a symbolic link "latest" that points to the latest slog dir --- meshtastic/slog/slog.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 0dd0690..bc8df62 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -152,6 +152,13 @@ class LogSet: app_dir = platformdirs.user_data_dir(app_name, app_author) dir_name = f"{app_dir}/slogs/{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 + # symlink might fail on some platforms, if it does fail silently + if os.path.exists(f"{app_dir}/slogs/latest"): + os.unlink(f"{app_dir}/slogs/latest") + os.symlink(dir_name, f"{app_dir}/slogs/latest", target_is_directory=True) + self.dir_name = dir_name logging.info(f"Writing slogs to {dir_name}") From d1aadf0c8ea7aa6b9ee9ee4d0c77a3be63795e2e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 12:22:47 -0700 Subject: [PATCH 052/248] close power meter gracefully --- meshtastic/powermon/power_supply.py | 3 +++ meshtastic/powermon/ppk2.py | 5 +++++ meshtastic/slog/slog.py | 1 + 3 files changed, 9 insertions(+) diff --git a/meshtastic/powermon/power_supply.py b/meshtastic/powermon/power_supply.py index cb4d044..50a3a83 100644 --- a/meshtastic/powermon/power_supply.py +++ b/meshtastic/powermon/power_supply.py @@ -20,6 +20,9 @@ class PowerMeter: self.prevPowerTime = datetime.now() self.prevWattHour = self._getRawWattHour() + def close(self) -> None: + """Close the power meter.""" + def getAverageWatts(self) -> float: """Get watts consumed since last call to this method.""" now = datetime.now() diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index bec4c1d..3ebf44f 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -37,6 +37,11 @@ class PPK2PowerSupply(PowerSupply): super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + def close(self) -> None: + """Close the power meter.""" + self.r.stop_measuring() + super().close() + def setIsSupply(self, s: bool): """If in supply mode we will provide power ourself, otherwise we are just an amp meter.""" if ( diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index bc8df62..31e3a14 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -73,6 +73,7 @@ class PowerLogger: def close(self) -> None: """Close the PowerLogger and stop logging.""" if self.is_logging: + self.pMeter.close() self.is_logging = False self.thread.join() self.writer.close() From f8ad4fef7c1e1faaf9ada59ab808827926a770ce Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 12:23:38 -0700 Subject: [PATCH 053/248] deferred execution thread should be named and marked as daemon --- meshtastic/util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index 3193802..ef12344 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -266,9 +266,10 @@ class Acknowledgment: class DeferredExecution: """A thread that accepts closures to run, and runs them as they are received""" - def __init__(self, name=None): + def __init__(self, name): self.queue = Queue() - self.thread = threading.Thread(target=self._run, args=(), name=name) + # this thread must be marked as daemon, otherwise it will prevent clients from exiting + self.thread = threading.Thread(target=self._run, args=(), name=name, daemon=True) self.thread.daemon = True self.thread.start() From ff20ad5d05aa3e8208edc03e38402ec2c6faee24 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 13:48:02 -0700 Subject: [PATCH 054/248] group power options in --help. add --power-wait to support some boards --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 63 +++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5add7d9..cef11f4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -180,7 +180,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-voltage", "3.3", "--port", "/dev/ttyUSB0", "--noproto", "--seriallog", "stdout"] + "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-wait", "--power-voltage", "3.3", "--noproto", "--seriallog", "stdout"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 0014ab3..ba4e6ec 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -985,9 +985,33 @@ def export_config(interface): print(config) return config +def create_power_meter(): + """Setup the power meter.""" + + args = mt_config.args + meter = None # assume no power meter + if args.power_riden: + meter = RidenPowerSupply(args.power_riden) + elif args.power_ppk2_supply or args.power_ppk2_meter: + meter = PPK2PowerSupply() + meter.setIsSupply(args.power_ppk2_supply) + elif args.power_sim: + meter = SimPowerSupply() + + if meter and args.power_voltage: + v = float(args.power_voltage) + if v < 0.5 or v >5.0: + meshtastic.util.our_exit("Voltage must be between 1.0 and 5.0") + 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...") + return meter def common(): - """Shared code for all of our command line wrappers""" + """Shared code for all of our command line wrappers.""" logfile = None args = mt_config.args parser = mt_config.parser @@ -1004,6 +1028,8 @@ def common(): meshtastic.util.support_info() meshtastic.util.our_exit("", 0) + meter = create_power_meter() + if args.ch_index is not None: channelIndex = int(args.ch_index) mt_config.channel_index = channelIndex @@ -1093,24 +1119,6 @@ def common(): # We assume client is fully connected now onConnected(client) - # Setup power meters - meter = None # assume no power meter - if args.power_riden: - meter = RidenPowerSupply(args.power_riden) - elif args.power_ppk2_supply or args.power_ppk2_meter: - meter = PPK2PowerSupply() - meter.setIsSupply(args.power_ppk2_supply) - elif args.power_sim: - meter = SimPowerSupply() - - if meter and args.power_voltage: - v = float(args.power_voltage) - if v < 0.5 or v >5.0: - meshtastic.util.our_exit("Voltage must be between 1.0 and 5.0") - logging.info(f"Setting power supply to {v} volts") - meter.v = v - meter.powerOn() - log_set = None if args.slog_out: # Setup loggers @@ -1533,7 +1541,9 @@ def initParser(): action="store_true", ) - power_supply_group = group.add_mutually_exclusive_group() + power_group = parser.add_argument_group('Power Testing', 'Options for power testing/logging.') + + power_supply_group = power_group.add_mutually_exclusive_group() power_supply_group.add_argument( "--power-riden", @@ -1558,21 +1568,28 @@ def initParser(): action="store_true", ) - group.add_argument( + power_group.add_argument( "--power-voltage", help="Set the specified voltage on the power-supply. Be VERY careful, you can burn things up.", ) - group.add_argument( + power_group.add_argument( "--power-stress", help="Perform power monitor stress testing, to capture a power consumption profile for the device (also requires --power-mon)", action="store_true", ) - group.add_argument( + power_group.add_argument( + "--power-wait", + help="Prompt the user to wait for device reset before looking for device serial ports (some boards kill power to USB serial port)", + action="store_true", + ) + + power_group.add_argument( "--slog-out", help="A directory to store structured logging to, or 'default' for automatically selected.", ) + group.add_argument( "--ble-scan", help="Scan for Meshtastic BLE devices", From 231bc25255ab79fa0135305a1967590c306bd167 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 15:19:21 -0700 Subject: [PATCH 055/248] PPK2 based power measurements seem to approximately work --- .vscode/settings.json | 1 + meshtastic/powermon/power_supply.py | 31 ++++++++-------- meshtastic/powermon/ppk2.py | 57 ++++++++++++++++++++++++++--- meshtastic/powermon/riden.py | 15 ++++++++ meshtastic/powermon/sim.py | 6 +-- meshtastic/slog/slog.py | 13 +++++-- 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f393e65..9b0d16e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "bitmask", "boardid", "Meshtastic", + "milliwatt", "powermon", "pyarrow", "TORADIO", diff --git a/meshtastic/powermon/power_supply.py b/meshtastic/powermon/power_supply.py index 50a3a83..89e61b0 100644 --- a/meshtastic/powermon/power_supply.py +++ b/meshtastic/powermon/power_supply.py @@ -18,28 +18,27 @@ class PowerMeter: def __init__(self): """Initialize the PowerMeter object.""" self.prevPowerTime = datetime.now() - self.prevWattHour = self._getRawWattHour() def close(self) -> None: """Close the power meter.""" - def getAverageWatts(self) -> float: - """Get watts consumed since last call to this method.""" - now = datetime.now() - nowWattHour = self._getRawWattHour() - watts = ( - (nowWattHour - self.prevWattHour) - / (now - self.prevPowerTime).total_seconds() - * 3600 - ) - self.prevPowerTime = now - self.prevWattHour = nowWattHour - return watts - - def _getRawWattHour(self) -> float: - """Get the current watt-hour reading (without any offset correction).""" + def get_average_current_mA(self) -> float: + """Returns average current of last measurement in mA (since last call to this method)""" return math.nan + def get_min_current_mA(self): + """Returns max current in mA (since last call to this method).""" + # Subclasses must override for a better implementation + return self.get_average_current_mA() + + def get_max_current_mA(self): + """Returns max current in mA (since last call to this method).""" + # Subclasses must override for a better implementation + return self.get_average_current_mA() + + def reset_measurements(self): + """Reset current measurements.""" + class PowerSupply(PowerMeter): """Abstract class for power supplies.""" diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 3ebf44f..53285fa 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -1,6 +1,8 @@ """Classes for logging power consumption of meshtastic devices.""" import logging +import threading +import time from typing import Optional from ppk2_api import ppk2_api # type: ignore[import-untyped] @@ -31,27 +33,70 @@ class PPK2PowerSupply(PowerSupply): self.r = r = ppk2_api.PPK2_MP(portName) # serial port will be different for you r.get_modifiers() - self.r.start_measuring() # start measuring - logging.info("Connected to PPK2 power supply") + self.r.start_measuring() # send command to ppk2 + self.current_measurements = [0.0] # reset current measurements to 0mA + self.measuring = True + + self.measurement_thread = threading.Thread( + target=self.measurement_loop, daemon=True, name="ppk2 measurement" + ) + self.measurement_thread.start() + + logging.info("Connected to Power Profiler Kit II (PPK2)") super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works + def measurement_loop(self): + """Endless measurement loop will run in a thread.""" + while self.measuring: + read_data = self.r.get_data() + if read_data != b"": + samples, _ = self.r.get_samples(read_data) + self.current_measurements += samples + time.sleep(0.001) # FIXME figure out correct sleep duration + + def get_min_current_mA(self): + """Returns max current in mA (since last call to this method).""" + return min(self.current_measurements) / 1000 + + def get_max_current_mA(self): + """Returns max current in mA (since last call to this method).""" + return max(self.current_measurements) / 1000 + + def get_average_current_mA(self): + """Returns average current in mA (since last call to this method).""" + average_current_mA = ( + sum(self.current_measurements) / len(self.current_measurements) + ) / 1000 # measurements are in microamperes, divide by 1000 + + return average_current_mA + + def reset_measurements(self): + """Reset current measurements.""" + # Use the last reading as the new only reading (to ensure we always have a valid current reading) + self.current_measurements = [ self.current_measurements[-1] ] + def close(self) -> None: """Close the power meter.""" - self.r.stop_measuring() + self.measuring = False + self.r.stop_measuring() # send command to ppk2 + self.measurement_thread.join() # wait for our thread to finish super().close() def setIsSupply(self, s: bool): """If in supply mode we will provide power ourself, otherwise we are just an amp meter.""" + + self.r.set_source_voltage( + int(self.v * 1000) + ) # set source voltage in mV BEFORE setting source mode + # Note: source voltage must be set even if we are using the amp meter mode + if ( not s ): # min power outpuf of PPK2. If less than this assume we want just meter mode. self.r.use_ampere_meter() else: - self.r.set_source_voltage( - int(self.v * 1000) - ) # set source voltage in mV BEFORE setting source mode self.r.use_source_meter() # set source meter mode def powerOn(self): diff --git a/meshtastic/powermon/riden.py b/meshtastic/powermon/riden.py index c425855..fd84b3b 100644 --- a/meshtastic/powermon/riden.py +++ b/meshtastic/powermon/riden.py @@ -23,6 +23,8 @@ class RidenPowerSupply(PowerSupply): f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated." ) r.set_date_time(datetime.now()) + self.prevWattHour = self._getRawWattHour() + self.nowWattHour = self.prevWattHour super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works def setMaxCurrent(self, i: float): @@ -36,6 +38,19 @@ class RidenPowerSupply(PowerSupply): ) # my WM1110 devboard header is directly connected to the 3.3V rail self.r.set_output(1) + def get_average_current_mA(self) -> float: + """Returns average current of last measurement in mA (since last call to this method)""" + now = datetime.now() + nowWattHour = self._getRawWattHour() + watts = ( + (nowWattHour - self.prevWattHour) + / (now - self.prevPowerTime).total_seconds() + * 3600 + ) + self.prevPowerTime = now + self.prevWattHour = nowWattHour + return watts / 1000 + def _getRawWattHour(self) -> float: """Get the current watt-hour reading.""" self.r.update() diff --git a/meshtastic/powermon/sim.py b/meshtastic/powermon/sim.py index e7e8484..796065b 100644 --- a/meshtastic/powermon/sim.py +++ b/meshtastic/powermon/sim.py @@ -9,8 +9,8 @@ from .power_supply import PowerSupply class SimPowerSupply(PowerSupply): """A simulated power supply for testing.""" - def getAverageWatts(self) -> float: - """Get the total amount of power that is currently being consumed.""" + def get_average_current_mA(self) -> float: + """Returns average current of last measurement in mA (since last call to this method)""" # Sim a 20mW load that varies sinusoidally - return (20 + 5 * math.sin(time.time())) / 1000 + return (20.0 + 5 * math.sin(time.time())) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 31e3a14..49ed62c 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -65,8 +65,13 @@ class PowerLogger: def _logging_thread(self) -> None: """Background thread for logging the current watts reading.""" while self.is_logging: - watts = self.pMeter.getAverageWatts() - d = {"time": datetime.now(), "watts": watts} + d = { + "time": datetime.now(), + "average_mW": self.pMeter.get_average_current_mA(), + "max_mW": self.pMeter.get_max_current_mA(), + "min_mW": self.pMeter.get_min_current_mA(), + } + self.pMeter.reset_measurements() self.writer.add_row(d) time.sleep(self.interval) @@ -164,7 +169,9 @@ class LogSet: logging.info(f"Writing slogs to {dir_name}") - self.slog_logger: Optional[StructuredLogger] = StructuredLogger(client, self.dir_name) + self.slog_logger: Optional[StructuredLogger] = StructuredLogger( + client, self.dir_name + ) self.power_logger: Optional[PowerLogger] = ( None if not power_meter From 9ab1b32bdb0dcc0b05ed2cae9483a880c6ac2e48 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 18:09:20 -0700 Subject: [PATCH 056/248] make pylint happy with a docstring --- meshtastic/tests/test_mesh_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 22950e5..810138c 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -688,6 +688,7 @@ def test_waitConnected_isConnected_timeout(capsys): @pytest.mark.unit def test_timeago(): + """Test that the _timeago function returns sane values""" assert _timeago(0) == "now" assert _timeago(1) == "1 sec ago" assert _timeago(15) == "15 secs ago" From 267923fdc5a7418254150904af6dc6f8a1461e35 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 18:14:07 -0700 Subject: [PATCH 057/248] Add hypothesis fuzzing test for _timeago --- meshtastic/tests/test_mesh_interface.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 810138c..5e8441c 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -5,6 +5,7 @@ import re from unittest.mock import MagicMock, patch import pytest +from hypothesis import given, strategies as st from .. import mesh_pb2, config_pb2, BROADCAST_ADDR, LOCAL_ADDR from ..mesh_interface import MeshInterface, _timeago @@ -696,3 +697,9 @@ def test_timeago(): assert _timeago(99999) == "1 day ago" assert _timeago(9999999) == "3 months ago" assert _timeago(-999) == "now" + +@given(seconds=st.integers()) +def test_timeago_fuzz(seconds): + """Fuzz _timeago to ensure it works with any integer""" + val = _timeago(seconds) + assert re.match(r"(now|\d+ (secs?|mins?|hours?|days?|months?|years?))", val) From 195f0c9d905f559342a8d13379ee75906e3000ba Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 18:24:04 -0700 Subject: [PATCH 058/248] drop timeago dep, concurrent PR --- poetry.lock | 13 ++----------- pyproject.toml | 1 - 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0e4c244..dd7228f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1098,6 +1098,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1193,16 +1194,6 @@ files = [ [package.extras] widechars = ["wcwidth"] -[[package]] -name = "timeago" -version = "1.0.16" -description = "A very simple python library, used to format datetime with `*** time ago` statement. eg: \"3 hours ago\"." -optional = false -python-versions = "*" -files = [ - {file = "timeago-1.0.16-py3-none-any.whl", hash = "sha256:9b8cb2e3102b329f35a04aa4531982d867b093b19481cfbb1dac7845fa2f79b0"}, -] - [[package]] name = "tomli" version = "2.0.1" @@ -1561,4 +1552,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.13" -content-hash = "ad7784653845f37d34feab43aa3947b8d6e51d7f4e51679a8730e26b98dbe453" +content-hash = "8548a8b432a3f62db158f5b35254b05b2599aafe75ef12100471937fd4603e3c" diff --git a/pyproject.toml b/pyproject.toml index 1ce1e4e..a22ddd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,6 @@ dotmap = "^1.3.30" pexpect = "^4.9.0" pyqrcode = "^1.2.1" tabulate = "^0.9.0" -timeago = "^1.0.16" webencodings = "^0.5.1" requests = "^2.31.0" pyparsing = "^3.1.2" From 4ca9aa29c2b352aa9e2bc992c7f9c1dc94748158 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 18:10:47 -0700 Subject: [PATCH 059/248] beginnings of meshtastic.analysis --- meshtastic/analysis/__init__.py | 1 + poetry.lock | 1643 ++++++++++++++++++++++++++++++- pyproject.toml | 11 + 3 files changed, 1636 insertions(+), 19 deletions(-) create mode 100644 meshtastic/analysis/__init__.py diff --git a/meshtastic/analysis/__init__.py b/meshtastic/analysis/__init__.py new file mode 100644 index 0000000..c6fda10 --- /dev/null +++ b/meshtastic/analysis/__init__.py @@ -0,0 +1 @@ +"""Post-run analysis tools for meshtastic.""" diff --git a/poetry.lock b/poetry.lock index af2ca49..23ce536 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,6 +11,115 @@ files = [ {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, ] +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "argon2-cffi" +version = "23.1.0" +description = "Argon2 for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, + {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, +] + +[package.dependencies] +argon2-cffi-bindings = "*" + +[package.extras] +dev = ["argon2-cffi[tests,typing]", "tox (>4)"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] +tests = ["hypothesis", "pytest"] +typing = ["mypy"] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +description = "Low-level CFFI bindings for Argon2" +optional = false +python-versions = ">=3.6" +files = [ + {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, + {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, +] + +[package.dependencies] +cffi = ">=1.0.1" + +[package.extras] +dev = ["cogapp", "pre-commit", "pytest", "wheel"] +tests = ["pytest"] + +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + [[package]] name = "astroid" version = "3.2.2" @@ -25,6 +134,38 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "async-lru" +version = "2.0.4" +description = "Simple LRU cache for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, + {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} + [[package]] name = "async-timeout" version = "4.0.3" @@ -70,6 +211,59 @@ files = [ pycodestyle = ">=2.12.0" tomli = {version = "*", markers = "python_version < \"3.11\""} +[[package]] +name = "babel" +version = "2.15.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bleach" +version = "6.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.3)"] + [[package]] name = "bleak" version = "0.21.1" @@ -128,6 +322,70 @@ files = [ {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -252,6 +510,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "comm" +version = "0.2.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + [[package]] name = "coverage" version = "7.5.4" @@ -362,6 +637,59 @@ files = [ {file = "dbus_fast-2.21.3.tar.gz", hash = "sha256:8d0f0f61d007c1316ce79cde35ed52c0ce8ce229fd0f0bf8c9af2013ab4516a7"}, ] +[[package]] +name = "debugpy" +version = "1.8.2" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7ee2e1afbf44b138c005e4380097d92532e1001580853a7cb40ed84e0ef1c3d2"}, + {file = "debugpy-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8c3f7c53130a070f0fc845a0f2cee8ed88d220d6b04595897b66605df1edd6"}, + {file = "debugpy-1.8.2-cp310-cp310-win32.whl", hash = "sha256:f179af1e1bd4c88b0b9f0fa153569b24f6b6f3de33f94703336363ae62f4bf47"}, + {file = "debugpy-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:0600faef1d0b8d0e85c816b8bb0cb90ed94fc611f308d5fde28cb8b3d2ff0fe3"}, + {file = "debugpy-1.8.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8a13417ccd5978a642e91fb79b871baded925d4fadd4dfafec1928196292aa0a"}, + {file = "debugpy-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acdf39855f65c48ac9667b2801234fc64d46778021efac2de7e50907ab90c634"}, + {file = "debugpy-1.8.2-cp311-cp311-win32.whl", hash = "sha256:2cbd4d9a2fc5e7f583ff9bf11f3b7d78dfda8401e8bb6856ad1ed190be4281ad"}, + {file = "debugpy-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:d3408fddd76414034c02880e891ea434e9a9cf3a69842098ef92f6e809d09afa"}, + {file = "debugpy-1.8.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:5d3ccd39e4021f2eb86b8d748a96c766058b39443c1f18b2dc52c10ac2757835"}, + {file = "debugpy-1.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62658aefe289598680193ff655ff3940e2a601765259b123dc7f89c0239b8cd3"}, + {file = "debugpy-1.8.2-cp312-cp312-win32.whl", hash = "sha256:bd11fe35d6fd3431f1546d94121322c0ac572e1bfb1f6be0e9b8655fb4ea941e"}, + {file = "debugpy-1.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:15bc2f4b0f5e99bf86c162c91a74c0631dbd9cef3c6a1d1329c946586255e859"}, + {file = "debugpy-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5a019d4574afedc6ead1daa22736c530712465c0c4cd44f820d803d937531b2d"}, + {file = "debugpy-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f062d6877d2e45b112c0bbade9a17aac507445fd638922b1a5434df34aed02"}, + {file = "debugpy-1.8.2-cp38-cp38-win32.whl", hash = "sha256:c78ba1680f1015c0ca7115671fe347b28b446081dada3fedf54138f44e4ba031"}, + {file = "debugpy-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf327316ae0c0e7dd81eb92d24ba8b5e88bb4d1b585b5c0d32929274a66a5210"}, + {file = "debugpy-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1523bc551e28e15147815d1397afc150ac99dbd3a8e64641d53425dba57b0ff9"}, + {file = "debugpy-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e24ccb0cd6f8bfaec68d577cb49e9c680621c336f347479b3fce060ba7c09ec1"}, + {file = "debugpy-1.8.2-cp39-cp39-win32.whl", hash = "sha256:7f8d57a98c5a486c5c7824bc0b9f2f11189d08d73635c326abef268f83950326"}, + {file = "debugpy-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:16c8dcab02617b75697a0a925a62943e26a0330da076e2a10437edd9f0bf3755"}, + {file = "debugpy-1.8.2-py2.py3-none-any.whl", hash = "sha256:16e16df3a98a35c63c3ab1e4d19be4cbc7fdda92d9ddc059294f18910928e0ca"}, + {file = "debugpy-1.8.2.zip", hash = "sha256:95378ed08ed2089221896b9b3a8d021e642c24edc8fef20e5d4342ca8be65c00"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + [[package]] name = "dill" version = "0.3.8" @@ -402,15 +730,110 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "fastjsonschema" +version = "2.20.0" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +files = [ + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" +files = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + [[package]] name = "hypothesis" -version = "6.104.0" +version = "6.104.1" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.104.0-py3-none-any.whl", hash = "sha256:4aaa38b57625abae0d377b2460b80a5847504dcce22985e3381e4373079d45d0"}, - {file = "hypothesis-6.104.0.tar.gz", hash = "sha256:f3f376491380aab841d706c562034c0118616dca7ce23e07b1a744c99f38d26b"}, + {file = "hypothesis-6.104.1-py3-none-any.whl", hash = "sha256:a0a898fa78ecaefe76ad248901dc274e598f29198c6015b3053f7f7827670e0e"}, + {file = "hypothesis-6.104.1.tar.gz", hash = "sha256:4033898019a6149823d2feeb8d214921b4ac2d342a05d6b02e40a3ca4be07eea"}, ] [package.dependencies] @@ -448,13 +871,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.1" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.1-py3-none-any.whl", hash = "sha256:ffef94b0b66046dd8ea2d619b701fe978d9264d38f3998bc4c27ec3b146a87c8"}, - {file = "importlib_metadata-7.2.1.tar.gz", hash = "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] @@ -476,6 +899,90 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "ipykernel" +version = "6.29.4" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, + {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.18.1" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +prompt-toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] + +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] + +[package.dependencies] +arrow = ">=0.15.0" + [[package]] name = "isort" version = "5.13.2" @@ -490,6 +997,317 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "json5" +version = "0.9.25" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8" +files = [ + {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"}, + {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonschema" +version = "4.22.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} +rpds-py = ">=0.7.1" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jupyter-client" +version = "8.6.2" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, + {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = ">=5.3" + +[package.extras] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-events" +version = "0.10.0" +description = "Jupyter Event System library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, + {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, +] + +[package.dependencies] +jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +referencing = "*" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001"}, + {file = "jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-server = ">=1.1.2" + +[[package]] +name = "jupyter-server" +version = "2.14.1" +description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server-2.14.1-py3-none-any.whl", hash = "sha256:16f7177c3a4ea8fe37784e2d31271981a812f0b2874af17339031dc3510cc2a5"}, + {file = "jupyter_server-2.14.1.tar.gz", hash = "sha256:12558d158ec7a0653bf96cc272bc7ad79e0127d503b982ed144399346694f726"}, +] + +[package.dependencies] +anyio = ">=3.1.0" +argon2-cffi = ">=21.1" +jinja2 = ">=3.0.3" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-events = ">=0.9.0" +jupyter-server-terminals = ">=0.4.4" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" +overrides = ">=5.0" +packaging = ">=22.0" +prometheus-client = ">=0.9" +pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} +pyzmq = ">=24" +send2trash = ">=1.8.2" +terminado = ">=0.8.3" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" +websocket-client = ">=1.7" + +[package.extras] +docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +description = "A Jupyter Server Extension Providing Terminals." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, + {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, +] + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab" +version = "4.2.2" +description = "JupyterLab computational environment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab-4.2.2-py3-none-any.whl", hash = "sha256:59ee9b839f43308c3dfd55d72d1f1a299ed42a7f91f2d1afe9c12a783f9e525f"}, + {file = "jupyterlab-4.2.2.tar.gz", hash = "sha256:a534b6a25719a92a40d514fb133a9fe8f0d9981b0bbce5d8a5fcaa33344a3038"}, +] + +[package.dependencies] +async-lru = ">=1.0.0" +httpx = ">=0.25.0" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +ipykernel = ">=6.5.0" +jinja2 = ">=3.0.3" +jupyter-core = "*" +jupyter-lsp = ">=2.0.0" +jupyter-server = ">=2.4.0,<3" +jupyterlab-server = ">=2.27.1,<3" +notebook-shim = ">=0.2" +packaging = "*" +setuptools = ">=40.1.0" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} +tornado = ">=6.2.0" +traitlets = "*" + +[package.extras] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.3.5)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] +docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] +test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] +upgrade-extension = ["copier (>=8,<10)", "jinja2-time (<0.3)", "pydantic (<2.0)", "pyyaml-include (<2.0)", "tomli-w (<2.0)"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + +[[package]] +name = "jupyterlab-server" +version = "2.27.2" +description = "A set of server components for JupyterLab and JupyterLab like applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_server-2.27.2-py3-none-any.whl", hash = "sha256:54aa2d64fd86383b5438d9f0c032f043c4d8c0264b8af9f60bd061157466ea43"}, + {file = "jupyterlab_server-2.27.2.tar.gz", hash = "sha256:15cbb349dc45e954e09bacf81b9f9bcb10815ff660fb2034ecd7417db3a7ea27"}, +] + +[package.dependencies] +babel = ">=2.10" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0.3" +json5 = ">=0.9.0" +jsonschema = ">=4.18.0" +jupyter-server = ">=1.21,<3" +packaging = ">=21.3" +requests = ">=2.31" + +[package.extras] +docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] +openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] + [[package]] name = "macholib" version = "1.16.3" @@ -610,6 +1428,20 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[package.dependencies] +traitlets = "*" + [[package]] name = "mccabe" version = "0.7.0" @@ -621,6 +1453,17 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mistune" +version = "3.0.2" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + [[package]] name = "modbus-tk" version = "1.1.3" @@ -708,6 +1551,115 @@ files = [ protobuf = ">=4.25.3" types-protobuf = ">=4.24" +[[package]] +name = "nbclient" +version = "0.10.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.4" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.16.4" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, + {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "!=5.0.0" +defusedxml = "*" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.1" + +[package.extras] +all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] +webpdf = ["playwright"] + +[[package]] +name = "nbformat" +version = "5.10.4" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, + {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, +] + +[package.dependencies] +fastjsonschema = ">=2.15" +jsonschema = ">=2.6" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +traitlets = ">=5.1" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +description = "A shim layer for notebook traits and config" +optional = false +python-versions = ">=3.7" +files = [ + {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, + {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, +] + +[package.dependencies] +jupyter-server = ">=1.8,<3" + +[package.extras] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] + [[package]] name = "numpy" version = "2.0.0" @@ -762,6 +1714,17 @@ files = [ {file = "numpy-2.0.0.tar.gz", hash = "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864"}, ] +[[package]] +name = "overrides" +version = "7.7.0" +description = "A decorator to automatically detect mismatch when overriding a method." +optional = false +python-versions = ">=3.6" +files = [ + {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, + {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, +] + [[package]] name = "packaging" version = "24.1" @@ -773,6 +1736,17 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + [[package]] name = "parse" version = "1.20.2" @@ -784,6 +1758,21 @@ files = [ {file = "parse-1.20.2.tar.gz", hash = "sha256:b41d604d16503c79d81af5165155c0b20f6c8d6c559efa66b4b695c3e5a0a0ce"}, ] +[[package]] +name = "parso" +version = "0.8.4" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] + +[package.extras] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] + [[package]] name = "pdoc3" version = "0.10.0" @@ -869,26 +1858,83 @@ files = [ [package.dependencies] pyserial = "*" +[[package]] +name = "prometheus-client" +version = "0.20.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, +] + +[package.extras] +twisted = ["twisted"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.47" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, +] + +[package.dependencies] +wcwidth = "*" + [[package]] name = "protobuf" -version = "5.27.1" +version = "5.27.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.27.1-cp310-abi3-win32.whl", hash = "sha256:3adc15ec0ff35c5b2d0992f9345b04a540c1e73bfee3ff1643db43cc1d734333"}, - {file = "protobuf-5.27.1-cp310-abi3-win_amd64.whl", hash = "sha256:25236b69ab4ce1bec413fd4b68a15ef8141794427e0b4dc173e9d5d9dffc3bcd"}, - {file = "protobuf-5.27.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e38fc29d7df32e01a41cf118b5a968b1efd46b9c41ff515234e794011c78b17"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:917ed03c3eb8a2d51c3496359f5b53b4e4b7e40edfbdd3d3f34336e0eef6825a"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:ee52874a9e69a30271649be88ecbe69d374232e8fd0b4e4b0aaaa87f429f1631"}, - {file = "protobuf-5.27.1-cp38-cp38-win32.whl", hash = "sha256:7a97b9c5aed86b9ca289eb5148df6c208ab5bb6906930590961e08f097258107"}, - {file = "protobuf-5.27.1-cp38-cp38-win_amd64.whl", hash = "sha256:f6abd0f69968792da7460d3c2cfa7d94fd74e1c21df321eb6345b963f9ec3d8d"}, - {file = "protobuf-5.27.1-cp39-cp39-win32.whl", hash = "sha256:dfddb7537f789002cc4eb00752c92e67885badcc7005566f2c5de9d969d3282d"}, - {file = "protobuf-5.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:39309898b912ca6febb0084ea912e976482834f401be35840a008da12d189340"}, - {file = "protobuf-5.27.1-py3-none-any.whl", hash = "sha256:4ac7249a1530a2ed50e24201d6630125ced04b30619262f06224616e0030b6cf"}, - {file = "protobuf-5.27.1.tar.gz", hash = "sha256:df5e5b8e39b7d1c25b186ffdf9f44f40f810bbcc9d2b71d9d3156fee5a9adf15"}, + {file = "protobuf-5.27.2-cp310-abi3-win32.whl", hash = "sha256:354d84fac2b0d76062e9b3221f4abbbacdfd2a4d8af36bab0474f3a0bb30ab38"}, + {file = "protobuf-5.27.2-cp310-abi3-win_amd64.whl", hash = "sha256:0e341109c609749d501986b835f667c6e1e24531096cff9d34ae411595e26505"}, + {file = "protobuf-5.27.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a109916aaac42bff84702fb5187f3edadbc7c97fc2c99c5ff81dd15dcce0d1e5"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:176c12b1f1c880bf7a76d9f7c75822b6a2bc3db2d28baa4d300e8ce4cde7409b"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b848dbe1d57ed7c191dfc4ea64b8b004a3f9ece4bf4d0d80a367b76df20bf36e"}, + {file = "protobuf-5.27.2-cp38-cp38-win32.whl", hash = "sha256:4fadd8d83e1992eed0248bc50a4a6361dc31bcccc84388c54c86e530b7f58863"}, + {file = "protobuf-5.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:610e700f02469c4a997e58e328cac6f305f649826853813177e6290416e846c6"}, + {file = "protobuf-5.27.2-cp39-cp39-win32.whl", hash = "sha256:9e8f199bf7f97bd7ecebffcae45ebf9527603549b2b562df0fbc6d4d688f14ca"}, + {file = "protobuf-5.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:7fc3add9e6003e026da5fc9e59b131b8f22b428b991ccd53e2af8071687b4fce"}, + {file = "protobuf-5.27.2-py3-none-any.whl", hash = "sha256:54330f07e4949d09614707c48b06d1a22f8ffb5763c159efd5c0928326a91470"}, + {file = "protobuf-5.27.2.tar.gz", hash = "sha256:f3ecdef226b9af856075f28227ff2c90ce3a594d092c39bee5513573f25e2714"}, ] +[[package]] +name = "psutil" +version = "6.0.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + [[package]] name = "ptyprocess" version = "0.7.0" @@ -900,6 +1946,20 @@ files = [ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "pyarrow" version = "16.1.0" @@ -969,6 +2029,31 @@ files = [ {file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"}, ] +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "pyinstaller" version = "6.8.0" @@ -1227,6 +2312,54 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-json-logger" +version = "2.0.7" +description = "A python library adding a json log formatter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, + {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, +] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + [[package]] name = "pywin32-ctypes" version = "0.2.2" @@ -1238,6 +2371,21 @@ files = [ {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, ] +[[package]] +name = "pywinpty" +version = "2.0.13" +description = "Pseudo terminal support for Windows from Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pywinpty-2.0.13-cp310-none-win_amd64.whl", hash = "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56"}, + {file = "pywinpty-2.0.13-cp311-none-win_amd64.whl", hash = "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99"}, + {file = "pywinpty-2.0.13-cp312-none-win_amd64.whl", hash = "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4"}, + {file = "pywinpty-2.0.13-cp38-none-win_amd64.whl", hash = "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d"}, + {file = "pywinpty-2.0.13-cp39-none-win_amd64.whl", hash = "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b"}, + {file = "pywinpty-2.0.13.tar.gz", hash = "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde"}, +] + [[package]] name = "pyyaml" version = "6.0.1" @@ -1297,6 +2445,121 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "pyzmq" +version = "26.0.3" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625"}, + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8"}, + {file = "pyzmq-26.0.3-cp310-cp310-win32.whl", hash = "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83"}, + {file = "pyzmq-26.0.3-cp311-cp311-win32.whl", hash = "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798"}, + {file = "pyzmq-26.0.3-cp312-cp312-win32.whl", hash = "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win32.whl", hash = "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97"}, + {file = "pyzmq-26.0.3-cp38-cp38-win32.whl", hash = "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc"}, + {file = "pyzmq-26.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920"}, + {file = "pyzmq-26.0.3-cp39-cp39-win32.whl", hash = "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad"}, + {file = "pyzmq-26.0.3.tar.gz", hash = "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "requests" version = "2.32.3" @@ -1318,6 +2581,31 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] + [[package]] name = "riden" version = "1.2.0" @@ -1338,6 +2626,130 @@ url = "https://github.com/geeksville/riden.git#1.2.1" reference = "HEAD" resolved_reference = "27fd58f069a089676dcaaea2ccb8dc8d24e4c6d9" +[[package]] +name = "rpds-py" +version = "0.18.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, +] + +[[package]] +name = "send2trash" +version = "1.8.3" +description = "Send file to trash natively under Mac OS X, Windows and Linux" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9"}, + {file = "Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf"}, +] + +[package.extras] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] +win32 = ["pywin32"] + [[package]] name = "setuptools" version = "70.1.1" @@ -1353,6 +2765,28 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1364,6 +2798,36 @@ files = [ {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] name = "tabulate" version = "0.9.0" @@ -1378,6 +2842,27 @@ files = [ [package.extras] widechars = ["wcwidth"] +[[package]] +name = "terminado" +version = "0.18.1" +description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, + {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, +] + +[package.dependencies] +ptyprocess = {version = "*", markers = "os_name != \"nt\""} +pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} +tornado = ">=6.1.0" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] +typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] + [[package]] name = "timeago" version = "1.0.16" @@ -1388,6 +2873,24 @@ files = [ {file = "timeago-1.0.16-py3-none-any.whl", hash = "sha256:9b8cb2e3102b329f35a04aa4531982d867b093b19481cfbb1dac7845fa2f79b0"}, ] +[[package]] +name = "tinycss2" +version = "1.3.0" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, + {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["pytest", "ruff"] + [[package]] name = "tomli" version = "2.0.1" @@ -1410,6 +2913,41 @@ files = [ {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] +[[package]] +name = "tornado" +version = "6.4.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] + [[package]] name = "types-protobuf" version = "5.26.0.20240422" @@ -1421,6 +2959,17 @@ files = [ {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, ] +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + [[package]] name = "types-pyyaml" version = "6.0.12.20240311" @@ -1479,6 +3028,20 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "uri-template" +version = "1.3.0" +description = "RFC 6570 URI Template Processor" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, + {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, +] + +[package.extras] +dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] + [[package]] name = "urllib3" version = "2.2.2" @@ -1496,6 +3059,32 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "webcolors" +version = "24.6.0" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.8" +files = [ + {file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"}, + {file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["coverage[toml]"] + [[package]] name = "webencodings" version = "0.5.1" @@ -1507,6 +3096,22 @@ files = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] +[[package]] +name = "websocket-client" +version = "1.8.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, + {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + [[package]] name = "winrt-runtime" version = "2.0.0b1" @@ -1746,4 +3351,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "ad12848e1311886733ea3205795e49e405c2012e9dcff2df6e926ef1cd1dd4b0" +content-hash = "f5f6125129dc3a7a3b1eb805a0315d0ff6db80eca9fd96a77429b034a1f47bc7" diff --git a/pyproject.toml b/pyproject.toml index e0b99b4..e26e937 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,16 @@ types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" pyarrow-stubs = "^10.0.1.7" + + + +# If you are doing power analysis you probably want these extra devtools +[tool.poetry.group.analysis] +optional = true + +[tool.poetry.group.analysis.dependencies] +jupyterlab = "^4.2.2" + [tool.poetry.extras] tunnel = ["pytap2"] @@ -58,6 +68,7 @@ mesh-tunnel = "meshtastic.__main__:tunnelMain [tunnel]" # then you can do stuff like "poe code" to run vscode inside this environment [tool.poe.tasks] code = "code ." +juypter = "poetry run jupyter lab" [build-system] requires = ["poetry-core"] From 1b14b1ef2068cab2a27d95b7d611739b2440256d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 18:58:27 -0700 Subject: [PATCH 060/248] Use poetry version --short for a valid tag name --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9fb71c3..8cdf3da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: - name: Get version id: get_version run: >- - poetry version + poetry version --short - name: Create GitHub release uses: actions/create-release@v1 From b063d33d775c45db1c657cad863032caa9f9650b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 18:58:32 -0700 Subject: [PATCH 061/248] don't git jupyter temp directories --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d064e44..d6f5bdc 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ __pycache__ examples/__pycache__ meshtastic.spec .hypothesis/ -coverage.xml \ No newline at end of file +coverage.xml +.ipynb_checkpoints \ No newline at end of file From 0b9af0dcba4adb6e3b9c199147605c991ff70664 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 25 Jun 2024 19:05:46 -0700 Subject: [PATCH 062/248] remove old protobufs (moving to meshtastic.protobuf) --- meshtastic/admin_pb2.py | 39 - meshtastic/admin_pb2.pyi | 557 ------ meshtastic/apponly_pb2.py | 28 - meshtastic/apponly_pb2.pyi | 54 - meshtastic/atak_pb2.py | 40 - meshtastic/atak_pb2.pyi | 464 ----- meshtastic/cannedmessages_pb2.py | 26 - meshtastic/cannedmessages_pb2.pyi | 37 - meshtastic/channel_pb2.py | 34 - meshtastic/channel_pb2.pyi | 231 --- meshtastic/clientonly_pb2.py | 27 - meshtastic/clientonly_pb2.pyi | 77 - meshtastic/config_pb2.py | 70 - meshtastic/config_pb2.pyi | 1508 --------------- meshtastic/connection_status_pb2.py | 36 - meshtastic/connection_status_pb2.pyi | 227 --- meshtastic/deviceonly_pb2.py | 46 - meshtastic/deviceonly_pb2.pyi | 386 ---- meshtastic/localonly_pb2.py | 30 - meshtastic/localonly_pb2.pyi | 204 --- meshtastic/mesh_pb2.py | 98 - meshtastic/mesh_pb2.pyi | 2526 -------------------------- meshtastic/module_config_pb2.py | 66 - meshtastic/module_config_pb2.pyi | 1184 ------------ meshtastic/mqtt_pb2.py | 30 - meshtastic/mqtt_pb2.pyi | 151 -- meshtastic/nanopb_pb2.py | 39 - meshtastic/nanopb_pb2.pyi | 321 ---- meshtastic/paxcount_pb2.py | 26 - meshtastic/paxcount_pb2.pyi | 49 - meshtastic/portnums_pb2.py | 26 - meshtastic/portnums_pb2.pyi | 369 ---- meshtastic/remote_hardware_pb2.py | 28 - meshtastic/remote_hardware_pb2.pyi | 125 -- meshtastic/rtttl_pb2.py | 26 - meshtastic/rtttl_pb2.pyi | 37 - meshtastic/storeforward_pb2.py | 34 - meshtastic/storeforward_pb2.pyi | 341 ---- meshtastic/telemetry_pb2.py | 36 - meshtastic/telemetry_pb2.pyi | 571 ------ meshtastic/xmodem_pb2.py | 28 - meshtastic/xmodem_pb2.pyi | 66 - 42 files changed, 10298 deletions(-) delete mode 100644 meshtastic/admin_pb2.py delete mode 100644 meshtastic/admin_pb2.pyi delete mode 100644 meshtastic/apponly_pb2.py delete mode 100644 meshtastic/apponly_pb2.pyi delete mode 100644 meshtastic/atak_pb2.py delete mode 100644 meshtastic/atak_pb2.pyi delete mode 100644 meshtastic/cannedmessages_pb2.py delete mode 100644 meshtastic/cannedmessages_pb2.pyi delete mode 100644 meshtastic/channel_pb2.py delete mode 100644 meshtastic/channel_pb2.pyi delete mode 100644 meshtastic/clientonly_pb2.py delete mode 100644 meshtastic/clientonly_pb2.pyi delete mode 100644 meshtastic/config_pb2.py delete mode 100644 meshtastic/config_pb2.pyi delete mode 100644 meshtastic/connection_status_pb2.py delete mode 100644 meshtastic/connection_status_pb2.pyi delete mode 100644 meshtastic/deviceonly_pb2.py delete mode 100644 meshtastic/deviceonly_pb2.pyi delete mode 100644 meshtastic/localonly_pb2.py delete mode 100644 meshtastic/localonly_pb2.pyi delete mode 100644 meshtastic/mesh_pb2.py delete mode 100644 meshtastic/mesh_pb2.pyi delete mode 100644 meshtastic/module_config_pb2.py delete mode 100644 meshtastic/module_config_pb2.pyi delete mode 100644 meshtastic/mqtt_pb2.py delete mode 100644 meshtastic/mqtt_pb2.pyi delete mode 100644 meshtastic/nanopb_pb2.py delete mode 100644 meshtastic/nanopb_pb2.pyi delete mode 100644 meshtastic/paxcount_pb2.py delete mode 100644 meshtastic/paxcount_pb2.pyi delete mode 100644 meshtastic/portnums_pb2.py delete mode 100644 meshtastic/portnums_pb2.pyi delete mode 100644 meshtastic/remote_hardware_pb2.py delete mode 100644 meshtastic/remote_hardware_pb2.pyi delete mode 100644 meshtastic/rtttl_pb2.py delete mode 100644 meshtastic/rtttl_pb2.pyi delete mode 100644 meshtastic/storeforward_pb2.py delete mode 100644 meshtastic/storeforward_pb2.pyi delete mode 100644 meshtastic/telemetry_pb2.py delete mode 100644 meshtastic/telemetry_pb2.pyi delete mode 100644 meshtastic/xmodem_pb2.py delete mode 100644 meshtastic/xmodem_pb2.pyi diff --git a/meshtastic/admin_pb2.py b/meshtastic/admin_pb2.py deleted file mode 100644 index e98de3e..0000000 --- a/meshtastic/admin_pb2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/admin.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2 -from meshtastic import config_pb2 as meshtastic_dot_config__pb2 -from meshtastic import connection_status_pb2 as meshtastic_dot_connection__status__pb2 -from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2 -from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/admin.proto\x12\nmeshtastic\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\"meshtastic/connection_status.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\"\xce\x11\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12\x33\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x13.meshtastic.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12.\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x10.meshtastic.UserH\x00\x12\x41\n\x12get_config_request\x18\x05 \x01(\x0e\x32#.meshtastic.AdminMessage.ConfigTypeH\x00\x12\x31\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x12.meshtastic.ConfigH\x00\x12N\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32).meshtastic.AdminMessage.ModuleConfigTypeH\x00\x12>\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\x18.meshtastic.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x42\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x1a.meshtastic.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12S\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\".meshtastic.DeviceConnectionStatusH\x00\x12\x31\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x19.meshtastic.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\\\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32*.meshtastic.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12%\n\tset_owner\x18 \x01(\x0b\x32\x10.meshtastic.UserH\x00\x12*\n\x0bset_channel\x18! \x01(\x0b\x32\x13.meshtastic.ChannelH\x00\x12(\n\nset_config\x18\" \x01(\x0b\x32\x12.meshtastic.ConfigH\x00\x12\x35\n\x11set_module_config\x18# \x01(\x0b\x32\x18.meshtastic.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12\x32\n\x12set_fixed_position\x18) \x01(\x0b\x32\x14.meshtastic.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"f\n\x1eNodeRemoteHardwarePinsResponse\x12\x44\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32!.meshtastic.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.admin_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _ADMINMESSAGE._serialized_start=181 - _ADMINMESSAGE._serialized_end=2435 - _ADMINMESSAGE_CONFIGTYPE._serialized_start=1949 - _ADMINMESSAGE_CONFIGTYPE._serialized_end=2098 - _ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=2101 - _ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=2416 - _HAMPARAMETERS._serialized_start=2437 - _HAMPARAMETERS._serialized_end=2528 - _NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=2530 - _NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=2632 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/admin_pb2.pyi b/meshtastic/admin_pb2.pyi deleted file mode 100644 index 8488f5b..0000000 --- a/meshtastic/admin_pb2.pyi +++ /dev/null @@ -1,557 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import meshtastic.channel_pb2 -import meshtastic.config_pb2 -import meshtastic.connection_status_pb2 -import meshtastic.mesh_pb2 -import meshtastic.module_config_pb2 -import sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class AdminMessage(google.protobuf.message.Message): - """ - This message is handled by the Admin module and is responsible for all settings/channel read/write operations. - This message is used to do settings operations to both remote AND local nodes. - (Prior to 1.2 these operations were done via special ToRadio operations) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _ConfigType: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _ConfigTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AdminMessage._ConfigType.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DEVICE_CONFIG: AdminMessage._ConfigType.ValueType # 0 - """ - TODO: REPLACE - """ - POSITION_CONFIG: AdminMessage._ConfigType.ValueType # 1 - """ - TODO: REPLACE - """ - POWER_CONFIG: AdminMessage._ConfigType.ValueType # 2 - """ - TODO: REPLACE - """ - NETWORK_CONFIG: AdminMessage._ConfigType.ValueType # 3 - """ - TODO: REPLACE - """ - DISPLAY_CONFIG: AdminMessage._ConfigType.ValueType # 4 - """ - TODO: REPLACE - """ - LORA_CONFIG: AdminMessage._ConfigType.ValueType # 5 - """ - TODO: REPLACE - """ - BLUETOOTH_CONFIG: AdminMessage._ConfigType.ValueType # 6 - """ - TODO: REPLACE - """ - - class ConfigType(_ConfigType, metaclass=_ConfigTypeEnumTypeWrapper): - """ - TODO: REPLACE - """ - - DEVICE_CONFIG: AdminMessage.ConfigType.ValueType # 0 - """ - TODO: REPLACE - """ - POSITION_CONFIG: AdminMessage.ConfigType.ValueType # 1 - """ - TODO: REPLACE - """ - POWER_CONFIG: AdminMessage.ConfigType.ValueType # 2 - """ - TODO: REPLACE - """ - NETWORK_CONFIG: AdminMessage.ConfigType.ValueType # 3 - """ - TODO: REPLACE - """ - DISPLAY_CONFIG: AdminMessage.ConfigType.ValueType # 4 - """ - TODO: REPLACE - """ - LORA_CONFIG: AdminMessage.ConfigType.ValueType # 5 - """ - TODO: REPLACE - """ - BLUETOOTH_CONFIG: AdminMessage.ConfigType.ValueType # 6 - """ - TODO: REPLACE - """ - - class _ModuleConfigType: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _ModuleConfigTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AdminMessage._ModuleConfigType.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - MQTT_CONFIG: AdminMessage._ModuleConfigType.ValueType # 0 - """ - TODO: REPLACE - """ - SERIAL_CONFIG: AdminMessage._ModuleConfigType.ValueType # 1 - """ - TODO: REPLACE - """ - EXTNOTIF_CONFIG: AdminMessage._ModuleConfigType.ValueType # 2 - """ - TODO: REPLACE - """ - STOREFORWARD_CONFIG: AdminMessage._ModuleConfigType.ValueType # 3 - """ - TODO: REPLACE - """ - RANGETEST_CONFIG: AdminMessage._ModuleConfigType.ValueType # 4 - """ - TODO: REPLACE - """ - TELEMETRY_CONFIG: AdminMessage._ModuleConfigType.ValueType # 5 - """ - TODO: REPLACE - """ - CANNEDMSG_CONFIG: AdminMessage._ModuleConfigType.ValueType # 6 - """ - TODO: REPLACE - """ - AUDIO_CONFIG: AdminMessage._ModuleConfigType.ValueType # 7 - """ - TODO: REPLACE - """ - REMOTEHARDWARE_CONFIG: AdminMessage._ModuleConfigType.ValueType # 8 - """ - TODO: REPLACE - """ - NEIGHBORINFO_CONFIG: AdminMessage._ModuleConfigType.ValueType # 9 - """ - TODO: REPLACE - """ - AMBIENTLIGHTING_CONFIG: AdminMessage._ModuleConfigType.ValueType # 10 - """ - TODO: REPLACE - """ - DETECTIONSENSOR_CONFIG: AdminMessage._ModuleConfigType.ValueType # 11 - """ - TODO: REPLACE - """ - PAXCOUNTER_CONFIG: AdminMessage._ModuleConfigType.ValueType # 12 - """ - TODO: REPLACE - """ - - class ModuleConfigType(_ModuleConfigType, metaclass=_ModuleConfigTypeEnumTypeWrapper): - """ - TODO: REPLACE - """ - - MQTT_CONFIG: AdminMessage.ModuleConfigType.ValueType # 0 - """ - TODO: REPLACE - """ - SERIAL_CONFIG: AdminMessage.ModuleConfigType.ValueType # 1 - """ - TODO: REPLACE - """ - EXTNOTIF_CONFIG: AdminMessage.ModuleConfigType.ValueType # 2 - """ - TODO: REPLACE - """ - STOREFORWARD_CONFIG: AdminMessage.ModuleConfigType.ValueType # 3 - """ - TODO: REPLACE - """ - RANGETEST_CONFIG: AdminMessage.ModuleConfigType.ValueType # 4 - """ - TODO: REPLACE - """ - TELEMETRY_CONFIG: AdminMessage.ModuleConfigType.ValueType # 5 - """ - TODO: REPLACE - """ - CANNEDMSG_CONFIG: AdminMessage.ModuleConfigType.ValueType # 6 - """ - TODO: REPLACE - """ - AUDIO_CONFIG: AdminMessage.ModuleConfigType.ValueType # 7 - """ - TODO: REPLACE - """ - REMOTEHARDWARE_CONFIG: AdminMessage.ModuleConfigType.ValueType # 8 - """ - TODO: REPLACE - """ - NEIGHBORINFO_CONFIG: AdminMessage.ModuleConfigType.ValueType # 9 - """ - TODO: REPLACE - """ - AMBIENTLIGHTING_CONFIG: AdminMessage.ModuleConfigType.ValueType # 10 - """ - TODO: REPLACE - """ - DETECTIONSENSOR_CONFIG: AdminMessage.ModuleConfigType.ValueType # 11 - """ - TODO: REPLACE - """ - PAXCOUNTER_CONFIG: AdminMessage.ModuleConfigType.ValueType # 12 - """ - TODO: REPLACE - """ - - GET_CHANNEL_REQUEST_FIELD_NUMBER: builtins.int - GET_CHANNEL_RESPONSE_FIELD_NUMBER: builtins.int - GET_OWNER_REQUEST_FIELD_NUMBER: builtins.int - GET_OWNER_RESPONSE_FIELD_NUMBER: builtins.int - GET_CONFIG_REQUEST_FIELD_NUMBER: builtins.int - GET_CONFIG_RESPONSE_FIELD_NUMBER: builtins.int - GET_MODULE_CONFIG_REQUEST_FIELD_NUMBER: builtins.int - GET_MODULE_CONFIG_RESPONSE_FIELD_NUMBER: builtins.int - GET_CANNED_MESSAGE_MODULE_MESSAGES_REQUEST_FIELD_NUMBER: builtins.int - GET_CANNED_MESSAGE_MODULE_MESSAGES_RESPONSE_FIELD_NUMBER: builtins.int - GET_DEVICE_METADATA_REQUEST_FIELD_NUMBER: builtins.int - GET_DEVICE_METADATA_RESPONSE_FIELD_NUMBER: builtins.int - GET_RINGTONE_REQUEST_FIELD_NUMBER: builtins.int - GET_RINGTONE_RESPONSE_FIELD_NUMBER: builtins.int - GET_DEVICE_CONNECTION_STATUS_REQUEST_FIELD_NUMBER: builtins.int - GET_DEVICE_CONNECTION_STATUS_RESPONSE_FIELD_NUMBER: builtins.int - SET_HAM_MODE_FIELD_NUMBER: builtins.int - GET_NODE_REMOTE_HARDWARE_PINS_REQUEST_FIELD_NUMBER: builtins.int - GET_NODE_REMOTE_HARDWARE_PINS_RESPONSE_FIELD_NUMBER: builtins.int - ENTER_DFU_MODE_REQUEST_FIELD_NUMBER: builtins.int - DELETE_FILE_REQUEST_FIELD_NUMBER: builtins.int - SET_OWNER_FIELD_NUMBER: builtins.int - SET_CHANNEL_FIELD_NUMBER: builtins.int - SET_CONFIG_FIELD_NUMBER: builtins.int - SET_MODULE_CONFIG_FIELD_NUMBER: builtins.int - SET_CANNED_MESSAGE_MODULE_MESSAGES_FIELD_NUMBER: builtins.int - SET_RINGTONE_MESSAGE_FIELD_NUMBER: builtins.int - REMOVE_BY_NODENUM_FIELD_NUMBER: builtins.int - SET_FAVORITE_NODE_FIELD_NUMBER: builtins.int - REMOVE_FAVORITE_NODE_FIELD_NUMBER: builtins.int - SET_FIXED_POSITION_FIELD_NUMBER: builtins.int - REMOVE_FIXED_POSITION_FIELD_NUMBER: builtins.int - BEGIN_EDIT_SETTINGS_FIELD_NUMBER: builtins.int - COMMIT_EDIT_SETTINGS_FIELD_NUMBER: builtins.int - REBOOT_OTA_SECONDS_FIELD_NUMBER: builtins.int - EXIT_SIMULATOR_FIELD_NUMBER: builtins.int - REBOOT_SECONDS_FIELD_NUMBER: builtins.int - SHUTDOWN_SECONDS_FIELD_NUMBER: builtins.int - FACTORY_RESET_FIELD_NUMBER: builtins.int - NODEDB_RESET_FIELD_NUMBER: builtins.int - get_channel_request: builtins.int - """ - Send the specified channel in the response to this message - NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) - """ - @property - def get_channel_response(self) -> meshtastic.channel_pb2.Channel: - """ - TODO: REPLACE - """ - get_owner_request: builtins.bool - """ - Send the current owner data in the response to this message. - """ - @property - def get_owner_response(self) -> meshtastic.mesh_pb2.User: - """ - TODO: REPLACE - """ - get_config_request: global___AdminMessage.ConfigType.ValueType - """ - Ask for the following config data to be sent - """ - @property - def get_config_response(self) -> meshtastic.config_pb2.Config: - """ - Send the current Config in the response to this message. - """ - get_module_config_request: global___AdminMessage.ModuleConfigType.ValueType - """ - Ask for the following config data to be sent - """ - @property - def get_module_config_response(self) -> meshtastic.module_config_pb2.ModuleConfig: - """ - Send the current Config in the response to this message. - """ - get_canned_message_module_messages_request: builtins.bool - """ - Get the Canned Message Module messages in the response to this message. - """ - get_canned_message_module_messages_response: builtins.str - """ - Get the Canned Message Module messages in the response to this message. - """ - get_device_metadata_request: builtins.bool - """ - Request the node to send device metadata (firmware, protobuf version, etc) - """ - @property - def get_device_metadata_response(self) -> meshtastic.mesh_pb2.DeviceMetadata: - """ - Device metadata response - """ - get_ringtone_request: builtins.bool - """ - Get the Ringtone in the response to this message. - """ - get_ringtone_response: builtins.str - """ - Get the Ringtone in the response to this message. - """ - get_device_connection_status_request: builtins.bool - """ - Request the node to send it's connection status - """ - @property - def get_device_connection_status_response(self) -> meshtastic.connection_status_pb2.DeviceConnectionStatus: - """ - Device connection status response - """ - @property - def set_ham_mode(self) -> global___HamParameters: - """ - Setup a node for licensed amateur (ham) radio operation - """ - get_node_remote_hardware_pins_request: builtins.bool - """ - Get the mesh's nodes with their available gpio pins for RemoteHardware module use - """ - @property - def get_node_remote_hardware_pins_response(self) -> global___NodeRemoteHardwarePinsResponse: - """ - Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use - """ - enter_dfu_mode_request: builtins.bool - """ - Enter (UF2) DFU mode - Only implemented on NRF52 currently - """ - delete_file_request: builtins.str - """ - Delete the file by the specified path from the device - """ - @property - def set_owner(self) -> meshtastic.mesh_pb2.User: - """ - Set the owner for this node - """ - @property - def set_channel(self) -> meshtastic.channel_pb2.Channel: - """ - Set channels (using the new API). - A special channel is the "primary channel". - The other records are secondary channels. - Note: only one channel can be marked as primary. - If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. - """ - @property - def set_config(self) -> meshtastic.config_pb2.Config: - """ - Set the current Config - """ - @property - def set_module_config(self) -> meshtastic.module_config_pb2.ModuleConfig: - """ - Set the current Config - """ - set_canned_message_module_messages: builtins.str - """ - Set the Canned Message Module messages text. - """ - set_ringtone_message: builtins.str - """ - Set the ringtone for ExternalNotification. - """ - remove_by_nodenum: builtins.int - """ - Remove the node by the specified node-num from the NodeDB on the device - """ - set_favorite_node: builtins.int - """ - Set specified node-num to be favorited on the NodeDB on the device - """ - remove_favorite_node: builtins.int - """ - Set specified node-num to be un-favorited on the NodeDB on the device - """ - @property - def set_fixed_position(self) -> meshtastic.mesh_pb2.Position: - """ - Set fixed position data on the node and then set the position.fixed_position = true - """ - remove_fixed_position: builtins.bool - """ - Clear fixed position coordinates and then set position.fixed_position = false - """ - begin_edit_settings: builtins.bool - """ - Begins an edit transaction for config, module config, owner, and channel settings changes - This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) - """ - commit_edit_settings: builtins.bool - """ - Commits an open transaction for any edits made to config, module config, owner, and channel settings - """ - reboot_ota_seconds: builtins.int - """ - Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) - Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. - """ - exit_simulator: builtins.bool - """ - This message is only supported for the simulator Portduino build. - If received the simulator will exit successfully. - """ - reboot_seconds: builtins.int - """ - Tell the node to reboot in this many seconds (or <0 to cancel reboot) - """ - shutdown_seconds: builtins.int - """ - Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) - """ - factory_reset: builtins.int - """ - Tell the node to factory reset, all device settings will be returned to factory defaults. - """ - nodedb_reset: builtins.int - """ - Tell the node to reset the nodedb. - """ - def __init__( - self, - *, - get_channel_request: builtins.int = ..., - get_channel_response: meshtastic.channel_pb2.Channel | None = ..., - get_owner_request: builtins.bool = ..., - get_owner_response: meshtastic.mesh_pb2.User | None = ..., - get_config_request: global___AdminMessage.ConfigType.ValueType = ..., - get_config_response: meshtastic.config_pb2.Config | None = ..., - get_module_config_request: global___AdminMessage.ModuleConfigType.ValueType = ..., - get_module_config_response: meshtastic.module_config_pb2.ModuleConfig | None = ..., - get_canned_message_module_messages_request: builtins.bool = ..., - get_canned_message_module_messages_response: builtins.str = ..., - get_device_metadata_request: builtins.bool = ..., - get_device_metadata_response: meshtastic.mesh_pb2.DeviceMetadata | None = ..., - get_ringtone_request: builtins.bool = ..., - get_ringtone_response: builtins.str = ..., - get_device_connection_status_request: builtins.bool = ..., - get_device_connection_status_response: meshtastic.connection_status_pb2.DeviceConnectionStatus | None = ..., - set_ham_mode: global___HamParameters | None = ..., - get_node_remote_hardware_pins_request: builtins.bool = ..., - get_node_remote_hardware_pins_response: global___NodeRemoteHardwarePinsResponse | None = ..., - enter_dfu_mode_request: builtins.bool = ..., - delete_file_request: builtins.str = ..., - set_owner: meshtastic.mesh_pb2.User | None = ..., - set_channel: meshtastic.channel_pb2.Channel | None = ..., - set_config: meshtastic.config_pb2.Config | None = ..., - set_module_config: meshtastic.module_config_pb2.ModuleConfig | None = ..., - set_canned_message_module_messages: builtins.str = ..., - set_ringtone_message: builtins.str = ..., - remove_by_nodenum: builtins.int = ..., - set_favorite_node: builtins.int = ..., - remove_favorite_node: builtins.int = ..., - set_fixed_position: meshtastic.mesh_pb2.Position | None = ..., - remove_fixed_position: builtins.bool = ..., - begin_edit_settings: builtins.bool = ..., - commit_edit_settings: builtins.bool = ..., - reboot_ota_seconds: builtins.int = ..., - exit_simulator: builtins.bool = ..., - reboot_seconds: builtins.int = ..., - shutdown_seconds: builtins.int = ..., - factory_reset: builtins.int = ..., - nodedb_reset: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.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_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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... - -global___AdminMessage = AdminMessage - -@typing_extensions.final -class HamParameters(google.protobuf.message.Message): - """ - Parameters for setting up Meshtastic for ameteur radio usage - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CALL_SIGN_FIELD_NUMBER: builtins.int - TX_POWER_FIELD_NUMBER: builtins.int - FREQUENCY_FIELD_NUMBER: builtins.int - SHORT_NAME_FIELD_NUMBER: builtins.int - call_sign: builtins.str - """ - Amateur radio call sign, eg. KD2ABC - """ - tx_power: builtins.int - """ - Transmit power in dBm at the LoRA transceiver, not including any amplification - """ - frequency: builtins.float - """ - The selected frequency of LoRA operation - Please respect your local laws, regulations, and band plans. - Ensure your radio is capable of operating of the selected frequency before setting this. - """ - short_name: builtins.str - """ - Optional short name of user - """ - def __init__( - self, - *, - call_sign: builtins.str = ..., - tx_power: builtins.int = ..., - frequency: builtins.float = ..., - short_name: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["call_sign", b"call_sign", "frequency", b"frequency", "short_name", b"short_name", "tx_power", b"tx_power"]) -> None: ... - -global___HamParameters = HamParameters - -@typing_extensions.final -class NodeRemoteHardwarePinsResponse(google.protobuf.message.Message): - """ - Response envelope for node_remote_hardware_pins - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: builtins.int - @property - def node_remote_hardware_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.mesh_pb2.NodeRemoteHardwarePin]: - """ - Nodes and their respective remote hardware GPIO pins - """ - def __init__( - self, - *, - node_remote_hardware_pins: collections.abc.Iterable[meshtastic.mesh_pb2.NodeRemoteHardwarePin] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["node_remote_hardware_pins", b"node_remote_hardware_pins"]) -> None: ... - -global___NodeRemoteHardwarePinsResponse = NodeRemoteHardwarePinsResponse diff --git a/meshtastic/apponly_pb2.py b/meshtastic/apponly_pb2.py deleted file mode 100644 index 46d9931..0000000 --- a/meshtastic/apponly_pb2.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/apponly.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2 -from meshtastic import config_pb2 as meshtastic_dot_config__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/apponly.proto\x12\nmeshtastic\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\"o\n\nChannelSet\x12-\n\x08settings\x18\x01 \x03(\x0b\x32\x1b.meshtastic.ChannelSettings\x12\x32\n\x0blora_config\x18\x02 \x01(\x0b\x32\x1d.meshtastic.Config.LoRaConfigBb\n\x13\x63om.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.apponly_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _CHANNELSET._serialized_start=91 - _CHANNELSET._serialized_end=202 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/apponly_pb2.pyi b/meshtastic/apponly_pb2.pyi deleted file mode 100644 index 0d84ed6..0000000 --- a/meshtastic/apponly_pb2.pyi +++ /dev/null @@ -1,54 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import meshtastic.channel_pb2 -import meshtastic.config_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ChannelSet(google.protobuf.message.Message): - """ - This is the most compact possible representation for a set of channels. - It includes only one PRIMARY channel (which must be first) and - any SECONDARY channels. - No DISABLED channels are included. - This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SETTINGS_FIELD_NUMBER: builtins.int - LORA_CONFIG_FIELD_NUMBER: builtins.int - @property - def settings(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.channel_pb2.ChannelSettings]: - """ - Channel list with settings - """ - @property - def lora_config(self) -> meshtastic.config_pb2.Config.LoRaConfig: - """ - LoRa config - """ - def __init__( - self, - *, - settings: collections.abc.Iterable[meshtastic.channel_pb2.ChannelSettings] | None = ..., - lora_config: meshtastic.config_pb2.Config.LoRaConfig | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["lora_config", b"lora_config"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["lora_config", b"lora_config", "settings", b"settings"]) -> None: ... - -global___ChannelSet = ChannelSet diff --git a/meshtastic/atak_pb2.py b/meshtastic/atak_pb2.py deleted file mode 100644 index a813729..0000000 --- a/meshtastic/atak_pb2.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/atak.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15meshtastic/atak.proto\x12\nmeshtastic\"\xe6\x01\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12$\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x13.meshtastic.Contact\x12 \n\x05group\x18\x03 \x01(\x0b\x32\x11.meshtastic.Group\x12\"\n\x06status\x18\x04 \x01(\x0b\x32\x12.meshtastic.Status\x12\x1e\n\x03pli\x18\x05 \x01(\x0b\x32\x0f.meshtastic.PLIH\x00\x12#\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x13.meshtastic.GeoChatH\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\"M\n\x05Group\x12$\n\x04role\x18\x01 \x01(\x0e\x32\x16.meshtastic.MemberRole\x12\x1e\n\x04team\x18\x02 \x01(\x0e\x32\x10.meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.atak_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _TEAM._serialized_start=622 - _TEAM._serialized_end=814 - _MEMBERROLE._serialized_start=816 - _MEMBERROLE._serialized_end=943 - _TAKPACKET._serialized_start=38 - _TAKPACKET._serialized_end=268 - _GEOCHAT._serialized_start=270 - _GEOCHAT._serialized_end=362 - _GROUP._serialized_start=364 - _GROUP._serialized_end=441 - _STATUS._serialized_start=443 - _STATUS._serialized_end=468 - _CONTACT._serialized_start=470 - _CONTACT._serialized_end=522 - _PLI._serialized_start=524 - _PLI._serialized_end=619 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/atak_pb2.pyi b/meshtastic/atak_pb2.pyi deleted file mode 100644 index 0cc35ef..0000000 --- a/meshtastic/atak_pb2.pyi +++ /dev/null @@ -1,464 +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 _Team: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _TeamEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Team.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - Unspecifed_Color: _Team.ValueType # 0 - """ - Unspecifed - """ - White: _Team.ValueType # 1 - """ - White - """ - Yellow: _Team.ValueType # 2 - """ - Yellow - """ - Orange: _Team.ValueType # 3 - """ - Orange - """ - Magenta: _Team.ValueType # 4 - """ - Magenta - """ - Red: _Team.ValueType # 5 - """ - Red - """ - Maroon: _Team.ValueType # 6 - """ - Maroon - """ - Purple: _Team.ValueType # 7 - """ - Purple - """ - Dark_Blue: _Team.ValueType # 8 - """ - Dark Blue - """ - Blue: _Team.ValueType # 9 - """ - Blue - """ - Cyan: _Team.ValueType # 10 - """ - Cyan - """ - Teal: _Team.ValueType # 11 - """ - Teal - """ - Green: _Team.ValueType # 12 - """ - Green - """ - Dark_Green: _Team.ValueType # 13 - """ - Dark Green - """ - Brown: _Team.ValueType # 14 - """ - Brown - """ - -class Team(_Team, metaclass=_TeamEnumTypeWrapper): ... - -Unspecifed_Color: Team.ValueType # 0 -""" -Unspecifed -""" -White: Team.ValueType # 1 -""" -White -""" -Yellow: Team.ValueType # 2 -""" -Yellow -""" -Orange: Team.ValueType # 3 -""" -Orange -""" -Magenta: Team.ValueType # 4 -""" -Magenta -""" -Red: Team.ValueType # 5 -""" -Red -""" -Maroon: Team.ValueType # 6 -""" -Maroon -""" -Purple: Team.ValueType # 7 -""" -Purple -""" -Dark_Blue: Team.ValueType # 8 -""" -Dark Blue -""" -Blue: Team.ValueType # 9 -""" -Blue -""" -Cyan: Team.ValueType # 10 -""" -Cyan -""" -Teal: Team.ValueType # 11 -""" -Teal -""" -Green: Team.ValueType # 12 -""" -Green -""" -Dark_Green: Team.ValueType # 13 -""" -Dark Green -""" -Brown: Team.ValueType # 14 -""" -Brown -""" -global___Team = Team - -class _MemberRole: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _MemberRoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MemberRole.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - Unspecifed: _MemberRole.ValueType # 0 - """ - Unspecifed - """ - TeamMember: _MemberRole.ValueType # 1 - """ - Team Member - """ - TeamLead: _MemberRole.ValueType # 2 - """ - Team Lead - """ - HQ: _MemberRole.ValueType # 3 - """ - Headquarters - """ - Sniper: _MemberRole.ValueType # 4 - """ - Airsoft enthusiast - """ - Medic: _MemberRole.ValueType # 5 - """ - Medic - """ - ForwardObserver: _MemberRole.ValueType # 6 - """ - ForwardObserver - """ - RTO: _MemberRole.ValueType # 7 - """ - Radio Telephone Operator - """ - K9: _MemberRole.ValueType # 8 - """ - Doggo - """ - -class MemberRole(_MemberRole, metaclass=_MemberRoleEnumTypeWrapper): - """ - Role of the group member - """ - -Unspecifed: MemberRole.ValueType # 0 -""" -Unspecifed -""" -TeamMember: MemberRole.ValueType # 1 -""" -Team Member -""" -TeamLead: MemberRole.ValueType # 2 -""" -Team Lead -""" -HQ: MemberRole.ValueType # 3 -""" -Headquarters -""" -Sniper: MemberRole.ValueType # 4 -""" -Airsoft enthusiast -""" -Medic: MemberRole.ValueType # 5 -""" -Medic -""" -ForwardObserver: MemberRole.ValueType # 6 -""" -ForwardObserver -""" -RTO: MemberRole.ValueType # 7 -""" -Radio Telephone Operator -""" -K9: MemberRole.ValueType # 8 -""" -Doggo -""" -global___MemberRole = MemberRole - -@typing_extensions.final -class TAKPacket(google.protobuf.message.Message): - """ - Packets for the official ATAK Plugin - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - IS_COMPRESSED_FIELD_NUMBER: builtins.int - CONTACT_FIELD_NUMBER: builtins.int - GROUP_FIELD_NUMBER: builtins.int - STATUS_FIELD_NUMBER: builtins.int - PLI_FIELD_NUMBER: builtins.int - CHAT_FIELD_NUMBER: builtins.int - is_compressed: builtins.bool - """ - Are the payloads strings compressed for LoRA transport? - """ - @property - def contact(self) -> global___Contact: - """ - The contact / callsign for ATAK user - """ - @property - def group(self) -> global___Group: - """ - The group for ATAK user - """ - @property - def status(self) -> global___Status: - """ - The status of the ATAK EUD - """ - @property - def pli(self) -> global___PLI: - """ - TAK position report - """ - @property - def chat(self) -> global___GeoChat: - """ - ATAK GeoChat message - """ - def __init__( - self, - *, - is_compressed: builtins.bool = ..., - contact: global___Contact | None = ..., - group: global___Group | None = ..., - status: global___Status | None = ..., - pli: global___PLI | None = ..., - chat: global___GeoChat | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "is_compressed", b"is_compressed", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["pli", "chat"] | None: ... - -global___TAKPacket = TAKPacket - -@typing_extensions.final -class GeoChat(google.protobuf.message.Message): - """ - ATAK GeoChat message - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MESSAGE_FIELD_NUMBER: builtins.int - TO_FIELD_NUMBER: builtins.int - TO_CALLSIGN_FIELD_NUMBER: builtins.int - message: builtins.str - """ - The text message - """ - to: builtins.str - """ - Uid recipient of the message - """ - to_callsign: builtins.str - """ - Callsign of the recipient for the message - """ - def __init__( - self, - *, - message: builtins.str = ..., - to: builtins.str | None = ..., - to_callsign: builtins.str | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "to", b"to", "to_callsign", b"to_callsign"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "message", b"message", "to", b"to", "to_callsign", b"to_callsign"]) -> None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_to", b"_to"]) -> typing_extensions.Literal["to"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_to_callsign", b"_to_callsign"]) -> typing_extensions.Literal["to_callsign"] | None: ... - -global___GeoChat = GeoChat - -@typing_extensions.final -class Group(google.protobuf.message.Message): - """ - ATAK Group - <__group role='Team Member' name='Cyan'/> - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ROLE_FIELD_NUMBER: builtins.int - TEAM_FIELD_NUMBER: builtins.int - role: global___MemberRole.ValueType - """ - Role of the group member - """ - team: global___Team.ValueType - """ - Team (color) - Default Cyan - """ - def __init__( - self, - *, - role: global___MemberRole.ValueType = ..., - team: global___Team.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["role", b"role", "team", b"team"]) -> None: ... - -global___Group = Group - -@typing_extensions.final -class Status(google.protobuf.message.Message): - """ - ATAK EUD Status - - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - BATTERY_FIELD_NUMBER: builtins.int - battery: builtins.int - """ - Battery level - """ - def __init__( - self, - *, - battery: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["battery", b"battery"]) -> None: ... - -global___Status = Status - -@typing_extensions.final -class Contact(google.protobuf.message.Message): - """ - ATAK Contact - - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CALLSIGN_FIELD_NUMBER: builtins.int - DEVICE_CALLSIGN_FIELD_NUMBER: builtins.int - callsign: builtins.str - """ - Callsign - """ - device_callsign: builtins.str - """ - Device callsign - - IP address of endpoint in integer form (0.0.0.0 default) - """ - def __init__( - self, - *, - callsign: builtins.str = ..., - device_callsign: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["callsign", b"callsign", "device_callsign", b"device_callsign"]) -> None: ... - -global___Contact = Contact - -@typing_extensions.final -class PLI(google.protobuf.message.Message): - """ - Position Location Information from ATAK - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LATITUDE_I_FIELD_NUMBER: builtins.int - LONGITUDE_I_FIELD_NUMBER: builtins.int - ALTITUDE_FIELD_NUMBER: builtins.int - SPEED_FIELD_NUMBER: builtins.int - COURSE_FIELD_NUMBER: builtins.int - latitude_i: builtins.int - """ - The new preferred location encoding, multiply by 1e-7 to get degrees - in floating point - """ - longitude_i: builtins.int - """ - The new preferred location encoding, multiply by 1e-7 to get degrees - in floating point - """ - altitude: builtins.int - """ - Altitude (ATAK prefers HAE) - """ - speed: builtins.int - """ - Speed - """ - course: builtins.int - """ - Course in degrees - """ - def __init__( - self, - *, - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - altitude: builtins.int = ..., - speed: builtins.int = ..., - course: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["altitude", b"altitude", "course", b"course", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i", "speed", b"speed"]) -> None: ... - -global___PLI = PLI diff --git a/meshtastic/cannedmessages_pb2.py b/meshtastic/cannedmessages_pb2.py deleted file mode 100644 index 058f3cf..0000000 --- a/meshtastic/cannedmessages_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/cannedmessages.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/cannedmessages.proto\x12\nmeshtastic\"-\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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.cannedmessages_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _CANNEDMESSAGEMODULECONFIG._serialized_start=47 - _CANNEDMESSAGEMODULECONFIG._serialized_end=92 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/cannedmessages_pb2.pyi b/meshtastic/cannedmessages_pb2.pyi deleted file mode 100644 index 9ee96bd..0000000 --- a/meshtastic/cannedmessages_pb2.pyi +++ /dev/null @@ -1,37 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class CannedMessageModuleConfig(google.protobuf.message.Message): - """ - Canned message module configuration. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MESSAGES_FIELD_NUMBER: builtins.int - messages: builtins.str - """ - Predefined messages for canned message module separated by '|' characters. - """ - def __init__( - self, - *, - messages: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["messages", b"messages"]) -> None: ... - -global___CannedMessageModuleConfig = CannedMessageModuleConfig diff --git a/meshtastic/channel_pb2.py b/meshtastic/channel_pb2.py deleted file mode 100644 index 2e66fe8..0000000 --- a/meshtastic/channel_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/channel.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/channel.proto\x12\nmeshtastic\"\xb8\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\x33\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32\x1a.meshtastic.ModuleSettings\"E\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x17\n\x0fis_client_muted\x18\x02 \x01(\x08\"\xa1\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12-\n\x08settings\x18\x02 \x01(\x0b\x32\x1b.meshtastic.ChannelSettings\x12&\n\x04role\x18\x03 \x01(\x0e\x32\x18.meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.channel_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - 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' - _CHANNELSETTINGS._serialized_start=41 - _CHANNELSETTINGS._serialized_end=225 - _MODULESETTINGS._serialized_start=227 - _MODULESETTINGS._serialized_end=296 - _CHANNEL._serialized_start=299 - _CHANNEL._serialized_end=460 - _CHANNEL_ROLE._serialized_start=412 - _CHANNEL_ROLE._serialized_end=460 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/channel_pb2.pyi b/meshtastic/channel_pb2.pyi deleted file mode 100644 index ff23a5f..0000000 --- a/meshtastic/channel_pb2.pyi +++ /dev/null @@ -1,231 +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 - -@typing_extensions.final -class ChannelSettings(google.protobuf.message.Message): - """ - This information can be encoded as a QRcode/url so that other users can configure - their radio to join the same channel. - A note about how channel names are shown to users: channelname-X - poundsymbol is a prefix used to indicate this is a channel name (idea from @professr). - Where X is a letter from A-Z (base 26) representing a hash of the PSK for this - channel - so that if the user changes anything about the channel (which does - force a new PSK) this letter will also change. Thus preventing user confusion if - two friends try to type in a channel name of "BobsChan" and then can't talk - because their PSKs will be different. - The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26" - This also allows the option of someday if people have the PSK off (zero), the - users COULD type in a channel name and be able to talk. - FIXME: Add description of multi-channel support and how primary vs secondary channels are used. - FIXME: explain how apps use channels for security. - explain how remote settings and remote gpio are managed as an example - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CHANNEL_NUM_FIELD_NUMBER: builtins.int - PSK_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - ID_FIELD_NUMBER: builtins.int - UPLINK_ENABLED_FIELD_NUMBER: builtins.int - DOWNLINK_ENABLED_FIELD_NUMBER: builtins.int - MODULE_SETTINGS_FIELD_NUMBER: builtins.int - channel_num: builtins.int - """ - Deprecated in favor of LoraConfig.channel_num - """ - psk: builtins.bytes - """ - A simple pre-shared key for now for crypto. - Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256). - A special shorthand is used for 1 byte long psks. - These psks should be treated as only minimally secure, - because they are listed in this source code. - Those bytes are mapped using the following scheme: - `0` = No crypto - `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01} - `2` through 10 = The default channel key, except with 1 through 9 added to the last byte. - Shown to user as simple1 through 10 - """ - name: builtins.str - """ - A SHORT name that will be packed into the URL. - Less than 12 bytes. - Something for end users to call the channel - If this is the empty string it is assumed that this channel - is the special (minimally secure) "Default"channel. - In user interfaces it should be rendered as a local language translation of "X". - For channel_num hashing empty string will be treated as "X". - Where "X" is selected based on the English words listed above for ModemPreset - """ - id: builtins.int - """ - Used to construct a globally unique channel ID. - The full globally unique ID will be: "name.id" where ID is shown as base36. - Assuming that the number of meshtastic users is below 20K (true for a long time) - the chance of this 64 bit random number colliding with anyone else is super low. - And the penalty for collision is low as well, it just means that anyone trying to decrypt channel messages might need to - try multiple candidate channels. - Any time a non wire compatible change is made to a channel, this field should be regenerated. - There are a small number of 'special' globally known (and fairly) insecure standard channels. - Those channels do not have a numeric id included in the settings, but instead it is pulled from - a table of well known IDs. - (see Well Known Channels FIXME) - """ - uplink_enabled: builtins.bool - """ - If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe - """ - downlink_enabled: builtins.bool - """ - If true, messages seen on the internet will be forwarded to the local mesh. - """ - @property - def module_settings(self) -> global___ModuleSettings: - """ - Per-channel module settings. - """ - def __init__( - self, - *, - channel_num: builtins.int = ..., - psk: builtins.bytes = ..., - name: builtins.str = ..., - id: builtins.int = ..., - uplink_enabled: builtins.bool = ..., - downlink_enabled: builtins.bool = ..., - module_settings: global___ModuleSettings | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["module_settings", b"module_settings"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["channel_num", b"channel_num", "downlink_enabled", b"downlink_enabled", "id", b"id", "module_settings", b"module_settings", "name", b"name", "psk", b"psk", "uplink_enabled", b"uplink_enabled"]) -> None: ... - -global___ChannelSettings = ChannelSettings - -@typing_extensions.final -class ModuleSettings(google.protobuf.message.Message): - """ - This message is specifically for modules to store per-channel configuration data. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - POSITION_PRECISION_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_client_muted: builtins.bool - """ - 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_client_muted: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["is_client_muted", b"is_client_muted", "position_precision", b"position_precision"]) -> None: ... - -global___ModuleSettings = ModuleSettings - -@typing_extensions.final -class Channel(google.protobuf.message.Message): - """ - A pair of a channel number, mode and the (sharable) settings for that channel - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Role: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _RoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Channel._Role.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DISABLED: Channel._Role.ValueType # 0 - """ - This channel is not in use right now - """ - PRIMARY: Channel._Role.ValueType # 1 - """ - This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY - """ - SECONDARY: Channel._Role.ValueType # 2 - """ - Secondary channels are only used for encryption/decryption/authentication purposes. - Their radio settings (freq etc) are ignored, only psk is used. - """ - - class Role(_Role, metaclass=_RoleEnumTypeWrapper): - """ - How this channel is being used (or not). - Note: this field is an enum to give us options for the future. - In particular, someday we might make a 'SCANNING' option. - SCANNING channels could have different frequencies and the radio would - occasionally check that freq to see if anything is being transmitted. - For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow - cross band routing as needed. - If a device has only a single radio (the common case) only one channel can be PRIMARY at a time - (but any number of SECONDARY channels can't be sent received on that common frequency) - """ - - DISABLED: Channel.Role.ValueType # 0 - """ - This channel is not in use right now - """ - PRIMARY: Channel.Role.ValueType # 1 - """ - This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY - """ - SECONDARY: Channel.Role.ValueType # 2 - """ - Secondary channels are only used for encryption/decryption/authentication purposes. - Their radio settings (freq etc) are ignored, only psk is used. - """ - - INDEX_FIELD_NUMBER: builtins.int - SETTINGS_FIELD_NUMBER: builtins.int - ROLE_FIELD_NUMBER: builtins.int - index: builtins.int - """ - The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) - (Someday - not currently implemented) An index of -1 could be used to mean "set by name", - in which case the target node will find and set the channel by settings.name. - """ - @property - def settings(self) -> global___ChannelSettings: - """ - The new settings, or NULL to disable that channel - """ - role: global___Channel.Role.ValueType - """ - TODO: REPLACE - """ - def __init__( - self, - *, - index: builtins.int = ..., - settings: global___ChannelSettings | None = ..., - role: global___Channel.Role.ValueType = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["settings", b"settings"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["index", b"index", "role", b"role", "settings", b"settings"]) -> None: ... - -global___Channel = Channel diff --git a/meshtastic/clientonly_pb2.py b/meshtastic/clientonly_pb2.py deleted file mode 100644 index 91e7b0d..0000000 --- a/meshtastic/clientonly_pb2.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/clientonly.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import localonly_pb2 as meshtastic_dot_localonly__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/clientonly.proto\x12\nmeshtastic\x1a\x1ameshtastic/localonly.proto\"\x8d\x02\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,\n\x06\x63onfig\x18\x04 \x01(\x0b\x32\x17.meshtastic.LocalConfigH\x03\x88\x01\x01\x12\x39\n\rmodule_config\x18\x05 \x01(\x0b\x32\x1d.meshtastic.LocalModuleConfigH\x04\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_configBe\n\x13\x63om.geeksville.meshB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.clientonly_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _DEVICEPROFILE._serialized_start=72 - _DEVICEPROFILE._serialized_end=341 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/clientonly_pb2.pyi b/meshtastic/clientonly_pb2.pyi deleted file mode 100644 index 10820e7..0000000 --- a/meshtastic/clientonly_pb2.pyi +++ /dev/null @@ -1,77 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import meshtastic.localonly_pb2 -import sys -import typing - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class DeviceProfile(google.protobuf.message.Message): - """ - This abstraction is used to contain any configuration for provisioning a node on any client. - It is useful for importing and exporting configurations. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LONG_NAME_FIELD_NUMBER: builtins.int - SHORT_NAME_FIELD_NUMBER: builtins.int - CHANNEL_URL_FIELD_NUMBER: builtins.int - CONFIG_FIELD_NUMBER: builtins.int - MODULE_CONFIG_FIELD_NUMBER: builtins.int - long_name: builtins.str - """ - Long name for the node - """ - short_name: builtins.str - """ - Short name of the node - """ - channel_url: builtins.str - """ - The url of the channels from our node - """ - @property - def config(self) -> meshtastic.localonly_pb2.LocalConfig: - """ - The Config of the node - """ - @property - def module_config(self) -> meshtastic.localonly_pb2.LocalModuleConfig: - """ - The ModuleConfig of the node - """ - def __init__( - self, - *, - long_name: builtins.str | None = ..., - short_name: builtins.str | None = ..., - channel_url: builtins.str | None = ..., - config: meshtastic.localonly_pb2.LocalConfig | None = ..., - module_config: meshtastic.localonly_pb2.LocalModuleConfig | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_channel_url", b"_channel_url"]) -> typing_extensions.Literal["channel_url"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_config", b"_config"]) -> typing_extensions.Literal["config"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_long_name", b"_long_name"]) -> typing_extensions.Literal["long_name"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_module_config", b"_module_config"]) -> typing_extensions.Literal["module_config"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_short_name", b"_short_name"]) -> typing_extensions.Literal["short_name"] | None: ... - -global___DeviceProfile = DeviceProfile diff --git a/meshtastic/config_pb2.py b/meshtastic/config_pb2.py deleted file mode 100644 index 9b216f9..0000000 --- a/meshtastic/config_pb2.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/config.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17meshtastic/config.proto\x12\nmeshtastic\"\xc2\x1f\n\x06\x43onfig\x12\x31\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x1f.meshtastic.Config.DeviceConfigH\x00\x12\x35\n\x08position\x18\x02 \x01(\x0b\x32!.meshtastic.Config.PositionConfigH\x00\x12/\n\x05power\x18\x03 \x01(\x0b\x32\x1e.meshtastic.Config.PowerConfigH\x00\x12\x33\n\x07network\x18\x04 \x01(\x0b\x32 .meshtastic.Config.NetworkConfigH\x00\x12\x33\n\x07\x64isplay\x18\x05 \x01(\x0b\x32 .meshtastic.Config.DisplayConfigH\x00\x12-\n\x04lora\x18\x06 \x01(\x0b\x32\x1d.meshtastic.Config.LoRaConfigH\x00\x12\x37\n\tbluetooth\x18\x07 \x01(\x0b\x32\".meshtastic.Config.BluetoothConfigH\x00\x1a\x91\x05\n\x0c\x44\x65viceConfig\x12\x32\n\x04role\x18\x01 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12I\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32/.meshtastic.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x91\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12;\n\x08gps_mode\x18\r \x01(\x0e\x32).meshtastic.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\xfe\x02\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12\x42\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32,.meshtastic.Config.NetworkConfig.AddressMode\x12@\n\x0bipv4_config\x18\x08 \x01(\x0b\x32+.meshtastic.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xbe\x05\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12H\n\ngps_format\x18\x02 \x01(\x0e\x32\x34.meshtastic.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12<\n\x05units\x18\x06 \x01(\x0e\x32-.meshtastic.Config.DisplayConfig.DisplayUnits\x12\x37\n\x04oled\x18\x07 \x01(\x0e\x32).meshtastic.Config.DisplayConfig.OledType\x12\x41\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32,.meshtastic.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\x1a\xb0\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12?\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32).meshtastic.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x38\n\x06region\x18\x07 \x01(\x0e\x32(.meshtastic.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xad\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12<\n\x04mode\x18\x02 \x01(\x0e\x32..meshtastic.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.config_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014ConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None - _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._serialized_options = b'\030\001' - _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None - _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' - _CONFIG._serialized_start=40 - _CONFIG._serialized_end=4074 - _CONFIG_DEVICECONFIG._serialized_start=416 - _CONFIG_DEVICECONFIG._serialized_end=1073 - _CONFIG_DEVICECONFIG_ROLE._serialized_start=820 - _CONFIG_DEVICECONFIG_ROLE._serialized_end=990 - _CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_start=992 - _CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_end=1073 - _CONFIG_POSITIONCONFIG._serialized_start=1076 - _CONFIG_POSITIONCONFIG._serialized_end=1733 - _CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_start=1507 - _CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_end=1678 - _CONFIG_POSITIONCONFIG_GPSMODE._serialized_start=1680 - _CONFIG_POSITIONCONFIG_GPSMODE._serialized_end=1733 - _CONFIG_POWERCONFIG._serialized_start=1736 - _CONFIG_POWERCONFIG._serialized_end=1970 - _CONFIG_NETWORKCONFIG._serialized_start=1973 - _CONFIG_NETWORKCONFIG._serialized_end=2355 - _CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_start=2248 - _CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_end=2318 - _CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_start=2320 - _CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_end=2355 - _CONFIG_DISPLAYCONFIG._serialized_start=2358 - _CONFIG_DISPLAYCONFIG._serialized_end=3060 - _CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT._serialized_start=2795 - _CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT._serialized_end=2872 - _CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_start=2874 - _CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_end=2914 - _CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_start=2916 - _CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_end=2993 - _CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_start=2995 - _CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_end=3060 - _CONFIG_LORACONFIG._serialized_start=3063 - _CONFIG_LORACONFIG._serialized_end=3879 - _CONFIG_LORACONFIG_REGIONCODE._serialized_start=3523 - _CONFIG_LORACONFIG_REGIONCODE._serialized_end=3728 - _CONFIG_LORACONFIG_MODEMPRESET._serialized_start=3731 - _CONFIG_LORACONFIG_MODEMPRESET._serialized_end=3879 - _CONFIG_BLUETOOTHCONFIG._serialized_start=3882 - _CONFIG_BLUETOOTHCONFIG._serialized_end=4055 - _CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_start=3999 - _CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_end=4055 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/config_pb2.pyi b/meshtastic/config_pb2.pyi deleted file mode 100644 index 4e864f0..0000000 --- a/meshtastic/config_pb2.pyi +++ /dev/null @@ -1,1508 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -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 - -@typing_extensions.final -class Config(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - @typing_extensions.final - class DeviceConfig(google.protobuf.message.Message): - """ - Configuration - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Role: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _RoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DeviceConfig._Role.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - CLIENT: Config.DeviceConfig._Role.ValueType # 0 - """ - Description: App connected or stand alone messaging device. - Technical Details: Default Role - """ - CLIENT_MUTE: Config.DeviceConfig._Role.ValueType # 1 - """ - Description: Device that does not forward packets from other devices. - """ - ROUTER: Config.DeviceConfig._Role.ValueType # 2 - """ - Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list. - Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps. - The wifi radio and the oled screen will be put to sleep. - This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. - """ - ROUTER_CLIENT: Config.DeviceConfig._Role.ValueType # 3 - """ - Description: Combination of both ROUTER and CLIENT. Not for mobile devices. - """ - REPEATER: Config.DeviceConfig._Role.ValueType # 4 - """ - 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. - """ - TRACKER: Config.DeviceConfig._Role.ValueType # 5 - """ - Description: Broadcasts GPS position packets as priority. - Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default. - When used in conjunction with power.is_power_saving = true, nodes will wake up, - send position, and then sleep for position.position_broadcast_secs seconds. - """ - SENSOR: Config.DeviceConfig._Role.ValueType # 6 - """ - Description: Broadcasts telemetry packets as priority. - Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default. - When used in conjunction with power.is_power_saving = true, nodes will wake up, - send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. - """ - TAK: Config.DeviceConfig._Role.ValueType # 7 - """ - Description: Optimized for ATAK system communication and reduces routine broadcasts. - Technical Details: Used for nodes dedicated for connection to an ATAK EUD. - Turns off many of the routine broadcasts to favor CoT packet stream - from the Meshtastic ATAK plugin -> IMeshService -> Node - """ - CLIENT_HIDDEN: Config.DeviceConfig._Role.ValueType # 8 - """ - Description: Device that only broadcasts as needed for stealth or power savings. - Technical Details: Used for nodes that "only speak when spoken to" - Turns all of the routine broadcasts but allows for ad-hoc communication - Still rebroadcasts, but with local only rebroadcast mode (known meshes only) - Can be used for clandestine operation or to dramatically reduce airtime / power consumption - """ - LOST_AND_FOUND: Config.DeviceConfig._Role.ValueType # 9 - """ - Description: Broadcasts location as message to default channel regularly for to assist with device recovery. - Technical Details: Used to automatically send a text message to the mesh - with the current position of the device on a frequent interval: - "I'm lost! Position: lat / long" - """ - TAK_TRACKER: Config.DeviceConfig._Role.ValueType # 10 - """ - Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts. - Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream - and automatic TAK PLI (position location information) broadcasts. - Uses position module configuration to determine TAK PLI broadcast interval. - """ - - class Role(_Role, metaclass=_RoleEnumTypeWrapper): - """ - Defines the device's role on the Mesh network - """ - - CLIENT: Config.DeviceConfig.Role.ValueType # 0 - """ - Description: App connected or stand alone messaging device. - Technical Details: Default Role - """ - CLIENT_MUTE: Config.DeviceConfig.Role.ValueType # 1 - """ - Description: Device that does not forward packets from other devices. - """ - ROUTER: Config.DeviceConfig.Role.ValueType # 2 - """ - Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list. - Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps. - The wifi radio and the oled screen will be put to sleep. - This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. - """ - ROUTER_CLIENT: Config.DeviceConfig.Role.ValueType # 3 - """ - Description: Combination of both ROUTER and CLIENT. Not for mobile devices. - """ - REPEATER: Config.DeviceConfig.Role.ValueType # 4 - """ - 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. - """ - TRACKER: Config.DeviceConfig.Role.ValueType # 5 - """ - Description: Broadcasts GPS position packets as priority. - Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default. - When used in conjunction with power.is_power_saving = true, nodes will wake up, - send position, and then sleep for position.position_broadcast_secs seconds. - """ - SENSOR: Config.DeviceConfig.Role.ValueType # 6 - """ - Description: Broadcasts telemetry packets as priority. - Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default. - When used in conjunction with power.is_power_saving = true, nodes will wake up, - send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. - """ - TAK: Config.DeviceConfig.Role.ValueType # 7 - """ - Description: Optimized for ATAK system communication and reduces routine broadcasts. - Technical Details: Used for nodes dedicated for connection to an ATAK EUD. - Turns off many of the routine broadcasts to favor CoT packet stream - from the Meshtastic ATAK plugin -> IMeshService -> Node - """ - CLIENT_HIDDEN: Config.DeviceConfig.Role.ValueType # 8 - """ - Description: Device that only broadcasts as needed for stealth or power savings. - Technical Details: Used for nodes that "only speak when spoken to" - Turns all of the routine broadcasts but allows for ad-hoc communication - Still rebroadcasts, but with local only rebroadcast mode (known meshes only) - Can be used for clandestine operation or to dramatically reduce airtime / power consumption - """ - LOST_AND_FOUND: Config.DeviceConfig.Role.ValueType # 9 - """ - Description: Broadcasts location as message to default channel regularly for to assist with device recovery. - Technical Details: Used to automatically send a text message to the mesh - with the current position of the device on a frequent interval: - "I'm lost! Position: lat / long" - """ - TAK_TRACKER: Config.DeviceConfig.Role.ValueType # 10 - """ - Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts. - Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream - and automatic TAK PLI (position location information) broadcasts. - Uses position module configuration to determine TAK PLI broadcast interval. - """ - - class _RebroadcastMode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _RebroadcastModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DeviceConfig._RebroadcastMode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - ALL: Config.DeviceConfig._RebroadcastMode.ValueType # 0 - """ - Default behavior. - Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. - """ - ALL_SKIP_DECODING: Config.DeviceConfig._RebroadcastMode.ValueType # 1 - """ - Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. - Only available in Repeater role. Setting this on any other roles will result in ALL behavior. - """ - LOCAL_ONLY: Config.DeviceConfig._RebroadcastMode.ValueType # 2 - """ - Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. - Only rebroadcasts message on the nodes local primary / secondary channels. - """ - KNOWN_ONLY: Config.DeviceConfig._RebroadcastMode.ValueType # 3 - """ - Ignores observed messages from foreign meshes like LOCAL_ONLY, - but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) - """ - - class RebroadcastMode(_RebroadcastMode, metaclass=_RebroadcastModeEnumTypeWrapper): - """ - Defines the device's behavior for how messages are rebroadcast - """ - - ALL: Config.DeviceConfig.RebroadcastMode.ValueType # 0 - """ - Default behavior. - Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. - """ - ALL_SKIP_DECODING: Config.DeviceConfig.RebroadcastMode.ValueType # 1 - """ - Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. - Only available in Repeater role. Setting this on any other roles will result in ALL behavior. - """ - LOCAL_ONLY: Config.DeviceConfig.RebroadcastMode.ValueType # 2 - """ - Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. - Only rebroadcasts message on the nodes local primary / secondary channels. - """ - KNOWN_ONLY: Config.DeviceConfig.RebroadcastMode.ValueType # 3 - """ - Ignores observed messages from foreign meshes like LOCAL_ONLY, - but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) - """ - - ROLE_FIELD_NUMBER: builtins.int - SERIAL_ENABLED_FIELD_NUMBER: builtins.int - DEBUG_LOG_ENABLED_FIELD_NUMBER: builtins.int - BUTTON_GPIO_FIELD_NUMBER: builtins.int - BUZZER_GPIO_FIELD_NUMBER: builtins.int - REBROADCAST_MODE_FIELD_NUMBER: builtins.int - NODE_INFO_BROADCAST_SECS_FIELD_NUMBER: builtins.int - DOUBLE_TAP_AS_BUTTON_PRESS_FIELD_NUMBER: builtins.int - IS_MANAGED_FIELD_NUMBER: builtins.int - DISABLE_TRIPLE_CLICK_FIELD_NUMBER: builtins.int - TZDEF_FIELD_NUMBER: builtins.int - LED_HEARTBEAT_DISABLED_FIELD_NUMBER: builtins.int - role: global___Config.DeviceConfig.Role.ValueType - """ - Sets the role of node - """ - serial_enabled: builtins.bool - """ - Disabling this will disable the SerialConsole by not initilizing the StreamAPI - """ - debug_log_enabled: builtins.bool - """ - By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). - Set this to true to leave the debug log outputting even when API is active. - """ - button_gpio: builtins.int - """ - For boards without a hard wired button, this is the pin number that will be used - Boards that have more than one button can swap the function with this one. defaults to BUTTON_PIN if defined. - """ - buzzer_gpio: builtins.int - """ - For boards without a PWM buzzer, this is the pin number that will be used - Defaults to PIN_BUZZER if defined. - """ - rebroadcast_mode: global___Config.DeviceConfig.RebroadcastMode.ValueType - """ - Sets the role of node - """ - node_info_broadcast_secs: builtins.int - """ - Send our nodeinfo this often - Defaults to 900 Seconds (15 minutes) - """ - double_tap_as_button_press: builtins.bool - """ - Treat double tap interrupt on supported accelerometers as a button press if set to true - """ - is_managed: builtins.bool - """ - If true, device is considered to be "managed" by a mesh administrator - Clients should then limit available configuration and administrative options inside the user interface - """ - disable_triple_click: builtins.bool - """ - Disables the triple-press of user button to enable or disable GPS - """ - tzdef: builtins.str - """ - POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. - """ - led_heartbeat_disabled: builtins.bool - """ - If true, disable the default blinking LED (LED_PIN) behavior on the device - """ - def __init__( - self, - *, - role: global___Config.DeviceConfig.Role.ValueType = ..., - serial_enabled: builtins.bool = ..., - debug_log_enabled: builtins.bool = ..., - button_gpio: builtins.int = ..., - buzzer_gpio: builtins.int = ..., - rebroadcast_mode: global___Config.DeviceConfig.RebroadcastMode.ValueType = ..., - node_info_broadcast_secs: builtins.int = ..., - double_tap_as_button_press: builtins.bool = ..., - is_managed: builtins.bool = ..., - disable_triple_click: builtins.bool = ..., - tzdef: builtins.str = ..., - led_heartbeat_disabled: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["button_gpio", b"button_gpio", "buzzer_gpio", b"buzzer_gpio", "debug_log_enabled", b"debug_log_enabled", "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_extensions.final - class PositionConfig(google.protobuf.message.Message): - """ - Position Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _PositionFlags: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _PositionFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.PositionConfig._PositionFlags.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: Config.PositionConfig._PositionFlags.ValueType # 0 - """ - Required for compilation - """ - ALTITUDE: Config.PositionConfig._PositionFlags.ValueType # 1 - """ - Include an altitude value (if available) - """ - ALTITUDE_MSL: Config.PositionConfig._PositionFlags.ValueType # 2 - """ - Altitude value is MSL - """ - GEOIDAL_SEPARATION: Config.PositionConfig._PositionFlags.ValueType # 4 - """ - Include geoidal separation - """ - DOP: Config.PositionConfig._PositionFlags.ValueType # 8 - """ - Include the DOP value ; PDOP used by default, see below - """ - HVDOP: Config.PositionConfig._PositionFlags.ValueType # 16 - """ - If POS_DOP set, send separate HDOP / VDOP values instead of PDOP - """ - SATINVIEW: Config.PositionConfig._PositionFlags.ValueType # 32 - """ - Include number of "satellites in view" - """ - SEQ_NO: Config.PositionConfig._PositionFlags.ValueType # 64 - """ - Include a sequence number incremented per packet - """ - TIMESTAMP: Config.PositionConfig._PositionFlags.ValueType # 128 - """ - Include positional timestamp (from GPS solution) - """ - HEADING: Config.PositionConfig._PositionFlags.ValueType # 256 - """ - Include positional heading - Intended for use with vehicle not walking speeds - walking speeds are likely to be error prone like the compass - """ - SPEED: Config.PositionConfig._PositionFlags.ValueType # 512 - """ - Include positional speed - Intended for use with vehicle not walking speeds - walking speeds are likely to be error prone like the compass - """ - - class PositionFlags(_PositionFlags, metaclass=_PositionFlagsEnumTypeWrapper): - """ - Bit field of boolean configuration options, indicating which optional - fields to include when assembling POSITION messages. - Longitude, latitude, altitude, speed, heading, and DOP - are always included (also time if GPS-synced) - NOTE: the more fields are included, the larger the message will be - - leading to longer airtime and a higher risk of packet loss - """ - - UNSET: Config.PositionConfig.PositionFlags.ValueType # 0 - """ - Required for compilation - """ - ALTITUDE: Config.PositionConfig.PositionFlags.ValueType # 1 - """ - Include an altitude value (if available) - """ - ALTITUDE_MSL: Config.PositionConfig.PositionFlags.ValueType # 2 - """ - Altitude value is MSL - """ - GEOIDAL_SEPARATION: Config.PositionConfig.PositionFlags.ValueType # 4 - """ - Include geoidal separation - """ - DOP: Config.PositionConfig.PositionFlags.ValueType # 8 - """ - Include the DOP value ; PDOP used by default, see below - """ - HVDOP: Config.PositionConfig.PositionFlags.ValueType # 16 - """ - If POS_DOP set, send separate HDOP / VDOP values instead of PDOP - """ - SATINVIEW: Config.PositionConfig.PositionFlags.ValueType # 32 - """ - Include number of "satellites in view" - """ - SEQ_NO: Config.PositionConfig.PositionFlags.ValueType # 64 - """ - Include a sequence number incremented per packet - """ - TIMESTAMP: Config.PositionConfig.PositionFlags.ValueType # 128 - """ - Include positional timestamp (from GPS solution) - """ - HEADING: Config.PositionConfig.PositionFlags.ValueType # 256 - """ - Include positional heading - Intended for use with vehicle not walking speeds - walking speeds are likely to be error prone like the compass - """ - SPEED: Config.PositionConfig.PositionFlags.ValueType # 512 - """ - Include positional speed - Intended for use with vehicle not walking speeds - walking speeds are likely to be error prone like the compass - """ - - class _GpsMode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _GpsModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.PositionConfig._GpsMode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DISABLED: Config.PositionConfig._GpsMode.ValueType # 0 - """ - GPS is present but disabled - """ - ENABLED: Config.PositionConfig._GpsMode.ValueType # 1 - """ - GPS is present and enabled - """ - NOT_PRESENT: Config.PositionConfig._GpsMode.ValueType # 2 - """ - GPS is not present on the device - """ - - class GpsMode(_GpsMode, metaclass=_GpsModeEnumTypeWrapper): ... - DISABLED: Config.PositionConfig.GpsMode.ValueType # 0 - """ - GPS is present but disabled - """ - ENABLED: Config.PositionConfig.GpsMode.ValueType # 1 - """ - GPS is present and enabled - """ - NOT_PRESENT: Config.PositionConfig.GpsMode.ValueType # 2 - """ - GPS is not present on the device - """ - - POSITION_BROADCAST_SECS_FIELD_NUMBER: builtins.int - POSITION_BROADCAST_SMART_ENABLED_FIELD_NUMBER: builtins.int - FIXED_POSITION_FIELD_NUMBER: builtins.int - GPS_ENABLED_FIELD_NUMBER: builtins.int - GPS_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - GPS_ATTEMPT_TIME_FIELD_NUMBER: builtins.int - POSITION_FLAGS_FIELD_NUMBER: builtins.int - RX_GPIO_FIELD_NUMBER: builtins.int - TX_GPIO_FIELD_NUMBER: builtins.int - BROADCAST_SMART_MINIMUM_DISTANCE_FIELD_NUMBER: builtins.int - BROADCAST_SMART_MINIMUM_INTERVAL_SECS_FIELD_NUMBER: builtins.int - GPS_EN_GPIO_FIELD_NUMBER: builtins.int - GPS_MODE_FIELD_NUMBER: builtins.int - position_broadcast_secs: builtins.int - """ - We should send our position this often (but only if it has changed significantly) - Defaults to 15 minutes - """ - position_broadcast_smart_enabled: builtins.bool - """ - Adaptive position braoadcast, which is now the default. - """ - fixed_position: builtins.bool - """ - If set, this node is at a fixed position. - We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node. - The lat/lon/alt can be set by an internal GPS or with the help of the app. - """ - gps_enabled: builtins.bool - """ - Is GPS enabled for this node? - """ - gps_update_interval: builtins.int - """ - How often should we try to get GPS position (in seconds) - or zero for the default of once every 30 seconds - or a very large value (maxint) to update only once at boot. - """ - gps_attempt_time: builtins.int - """ - Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time - """ - position_flags: builtins.int - """ - Bit field of boolean configuration options for POSITION messages - (bitwise OR of PositionFlags) - """ - rx_gpio: builtins.int - """ - (Re)define GPS_RX_PIN for your board. - """ - tx_gpio: builtins.int - """ - (Re)define GPS_TX_PIN for your board. - """ - broadcast_smart_minimum_distance: builtins.int - """ - The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled - """ - broadcast_smart_minimum_interval_secs: builtins.int - """ - The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled - """ - gps_en_gpio: builtins.int - """ - (Re)define PIN_GPS_EN for your board. - """ - gps_mode: global___Config.PositionConfig.GpsMode.ValueType - """ - Set where GPS is enabled, disabled, or not present - """ - def __init__( - self, - *, - position_broadcast_secs: builtins.int = ..., - position_broadcast_smart_enabled: builtins.bool = ..., - fixed_position: builtins.bool = ..., - gps_enabled: builtins.bool = ..., - gps_update_interval: builtins.int = ..., - gps_attempt_time: builtins.int = ..., - position_flags: builtins.int = ..., - rx_gpio: builtins.int = ..., - tx_gpio: builtins.int = ..., - broadcast_smart_minimum_distance: builtins.int = ..., - broadcast_smart_minimum_interval_secs: builtins.int = ..., - gps_en_gpio: builtins.int = ..., - gps_mode: global___Config.PositionConfig.GpsMode.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["broadcast_smart_minimum_distance", b"broadcast_smart_minimum_distance", "broadcast_smart_minimum_interval_secs", b"broadcast_smart_minimum_interval_secs", "fixed_position", b"fixed_position", "gps_attempt_time", b"gps_attempt_time", "gps_en_gpio", b"gps_en_gpio", "gps_enabled", b"gps_enabled", "gps_mode", b"gps_mode", "gps_update_interval", b"gps_update_interval", "position_broadcast_secs", b"position_broadcast_secs", "position_broadcast_smart_enabled", b"position_broadcast_smart_enabled", "position_flags", b"position_flags", "rx_gpio", b"rx_gpio", "tx_gpio", b"tx_gpio"]) -> None: ... - - @typing_extensions.final - class PowerConfig(google.protobuf.message.Message): - """ - Power Config\\ - See [Power Config](/docs/settings/config/power) for additional power config details. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - IS_POWER_SAVING_FIELD_NUMBER: builtins.int - ON_BATTERY_SHUTDOWN_AFTER_SECS_FIELD_NUMBER: builtins.int - ADC_MULTIPLIER_OVERRIDE_FIELD_NUMBER: builtins.int - WAIT_BLUETOOTH_SECS_FIELD_NUMBER: builtins.int - SDS_SECS_FIELD_NUMBER: builtins.int - LS_SECS_FIELD_NUMBER: builtins.int - MIN_WAKE_SECS_FIELD_NUMBER: builtins.int - DEVICE_BATTERY_INA_ADDRESS_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. - 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 - """ - on_battery_shutdown_after_secs: builtins.int - """ - Description: If non-zero, the device will fully power off this many seconds after external power is removed. - """ - adc_multiplier_override: builtins.float - """ - Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) - Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. - https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override - Should be set to floating point value between 2 and 6 - """ - wait_bluetooth_secs: builtins.int - """ - Description: The number of seconds for to wait before turning off BLE in No Bluetooth states - Technical Details: ESP32 Only 0 for default of 1 minute - """ - sds_secs: builtins.int - """ - Super Deep Sleep Seconds - While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep - for this value (default 1 year) or a button press - 0 for default of one year - """ - ls_secs: builtins.int - """ - Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on - Technical Details: ESP32 Only 0 for default of 300 - """ - min_wake_secs: builtins.int - """ - Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value - Technical Details: ESP32 Only 0 for default of 10 seconds - """ - device_battery_ina_address: builtins.int - """ - I2C address of INA_2XX to use for reading device battery voltage - """ - def __init__( - self, - *, - is_power_saving: builtins.bool = ..., - on_battery_shutdown_after_secs: builtins.int = ..., - adc_multiplier_override: builtins.float = ..., - wait_bluetooth_secs: builtins.int = ..., - sds_secs: builtins.int = ..., - ls_secs: builtins.int = ..., - min_wake_secs: builtins.int = ..., - device_battery_ina_address: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... - - @typing_extensions.final - class NetworkConfig(google.protobuf.message.Message): - """ - Network Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _AddressMode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _AddressModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.NetworkConfig._AddressMode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DHCP: Config.NetworkConfig._AddressMode.ValueType # 0 - """ - obtain ip address via DHCP - """ - STATIC: Config.NetworkConfig._AddressMode.ValueType # 1 - """ - use static ip address - """ - - class AddressMode(_AddressMode, metaclass=_AddressModeEnumTypeWrapper): ... - DHCP: Config.NetworkConfig.AddressMode.ValueType # 0 - """ - obtain ip address via DHCP - """ - STATIC: Config.NetworkConfig.AddressMode.ValueType # 1 - """ - use static ip address - """ - - @typing_extensions.final - class IpV4Config(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - IP_FIELD_NUMBER: builtins.int - GATEWAY_FIELD_NUMBER: builtins.int - SUBNET_FIELD_NUMBER: builtins.int - DNS_FIELD_NUMBER: builtins.int - ip: builtins.int - """ - Static IP address - """ - gateway: builtins.int - """ - Static gateway address - """ - subnet: builtins.int - """ - Static subnet mask - """ - dns: builtins.int - """ - Static DNS server address - """ - def __init__( - self, - *, - ip: builtins.int = ..., - gateway: builtins.int = ..., - subnet: builtins.int = ..., - dns: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["dns", b"dns", "gateway", b"gateway", "ip", b"ip", "subnet", b"subnet"]) -> None: ... - - WIFI_ENABLED_FIELD_NUMBER: builtins.int - WIFI_SSID_FIELD_NUMBER: builtins.int - WIFI_PSK_FIELD_NUMBER: builtins.int - NTP_SERVER_FIELD_NUMBER: builtins.int - ETH_ENABLED_FIELD_NUMBER: builtins.int - ADDRESS_MODE_FIELD_NUMBER: builtins.int - IPV4_CONFIG_FIELD_NUMBER: builtins.int - RSYSLOG_SERVER_FIELD_NUMBER: builtins.int - wifi_enabled: builtins.bool - """ - Enable WiFi (disables Bluetooth) - """ - wifi_ssid: builtins.str - """ - If set, this node will try to join the specified wifi network and - acquire an address via DHCP - """ - wifi_psk: builtins.str - """ - If set, will be use to authenticate to the named wifi - """ - ntp_server: builtins.str - """ - NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` - """ - eth_enabled: builtins.bool - """ - Enable Ethernet - """ - address_mode: global___Config.NetworkConfig.AddressMode.ValueType - """ - acquire an address via DHCP or assign static - """ - @property - def ipv4_config(self) -> global___Config.NetworkConfig.IpV4Config: - """ - struct to keep static address - """ - rsyslog_server: builtins.str - """ - rsyslog Server and Port - """ - def __init__( - self, - *, - wifi_enabled: builtins.bool = ..., - wifi_ssid: builtins.str = ..., - wifi_psk: builtins.str = ..., - ntp_server: builtins.str = ..., - eth_enabled: builtins.bool = ..., - address_mode: global___Config.NetworkConfig.AddressMode.ValueType = ..., - ipv4_config: global___Config.NetworkConfig.IpV4Config | None = ..., - rsyslog_server: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["ipv4_config", b"ipv4_config"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address_mode", b"address_mode", "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_extensions.final - class DisplayConfig(google.protobuf.message.Message): - """ - Display Config - """ - - 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[Config.DisplayConfig._GpsCoordinateFormat.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - 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 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) - V: typing_extensions.TypeAlias = ValueType - - class _DisplayUnitsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._DisplayUnits.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - METRIC: Config.DisplayConfig._DisplayUnits.ValueType # 0 - """ - Metric (Default) - """ - IMPERIAL: Config.DisplayConfig._DisplayUnits.ValueType # 1 - """ - Imperial - """ - - class DisplayUnits(_DisplayUnits, metaclass=_DisplayUnitsEnumTypeWrapper): - """ - Unit display preference - """ - - METRIC: Config.DisplayConfig.DisplayUnits.ValueType # 0 - """ - Metric (Default) - """ - IMPERIAL: Config.DisplayConfig.DisplayUnits.ValueType # 1 - """ - Imperial - """ - - class _OledType: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _OledTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._OledType.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - OLED_AUTO: Config.DisplayConfig._OledType.ValueType # 0 - """ - Default / Auto - """ - OLED_SSD1306: Config.DisplayConfig._OledType.ValueType # 1 - """ - Default / Auto - """ - OLED_SH1106: Config.DisplayConfig._OledType.ValueType # 2 - """ - Default / Auto - """ - OLED_SH1107: Config.DisplayConfig._OledType.ValueType # 3 - """ - Can not be auto detected but set by proto. Used for 128x128 screens - """ - - class OledType(_OledType, metaclass=_OledTypeEnumTypeWrapper): - """ - Override OLED outo detect with this if it fails. - """ - - OLED_AUTO: Config.DisplayConfig.OledType.ValueType # 0 - """ - Default / Auto - """ - OLED_SSD1306: Config.DisplayConfig.OledType.ValueType # 1 - """ - Default / Auto - """ - OLED_SH1106: Config.DisplayConfig.OledType.ValueType # 2 - """ - Default / Auto - """ - OLED_SH1107: Config.DisplayConfig.OledType.ValueType # 3 - """ - Can not be auto detected but set by proto. Used for 128x128 screens - """ - - class _DisplayMode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _DisplayModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._DisplayMode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DEFAULT: Config.DisplayConfig._DisplayMode.ValueType # 0 - """ - Default. The old style for the 128x64 OLED screen - """ - TWOCOLOR: Config.DisplayConfig._DisplayMode.ValueType # 1 - """ - Rearrange display elements to cater for bicolor OLED displays - """ - INVERTED: Config.DisplayConfig._DisplayMode.ValueType # 2 - """ - Same as TwoColor, but with inverted top bar. Not so good for Epaper displays - """ - COLOR: Config.DisplayConfig._DisplayMode.ValueType # 3 - """ - TFT Full Color Displays (not implemented yet) - """ - - class DisplayMode(_DisplayMode, metaclass=_DisplayModeEnumTypeWrapper): ... - DEFAULT: Config.DisplayConfig.DisplayMode.ValueType # 0 - """ - Default. The old style for the 128x64 OLED screen - """ - TWOCOLOR: Config.DisplayConfig.DisplayMode.ValueType # 1 - """ - Rearrange display elements to cater for bicolor OLED displays - """ - INVERTED: Config.DisplayConfig.DisplayMode.ValueType # 2 - """ - Same as TwoColor, but with inverted top bar. Not so good for Epaper displays - """ - COLOR: Config.DisplayConfig.DisplayMode.ValueType # 3 - """ - TFT Full Color Displays (not implemented yet) - """ - - SCREEN_ON_SECS_FIELD_NUMBER: builtins.int - GPS_FORMAT_FIELD_NUMBER: builtins.int - AUTO_SCREEN_CAROUSEL_SECS_FIELD_NUMBER: builtins.int - COMPASS_NORTH_TOP_FIELD_NUMBER: builtins.int - FLIP_SCREEN_FIELD_NUMBER: builtins.int - UNITS_FIELD_NUMBER: builtins.int - OLED_FIELD_NUMBER: builtins.int - DISPLAYMODE_FIELD_NUMBER: builtins.int - HEADING_BOLD_FIELD_NUMBER: builtins.int - WAKE_ON_TAP_OR_MOTION_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.GpsCoordinateFormat.ValueType - """ - How the GPS coordinates are formatted on the OLED screen. - """ - auto_screen_carousel_secs: builtins.int - """ - Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds. - Potentially useful for devices without user buttons. - """ - compass_north_top: builtins.bool - """ - If this is set, the displayed compass will always point north. if unset, the old behaviour - (top of display is heading direction) is used. - """ - flip_screen: builtins.bool - """ - Flip screen vertically, for cases that mount the screen upside down - """ - units: global___Config.DisplayConfig.DisplayUnits.ValueType - """ - Perferred display units - """ - oled: global___Config.DisplayConfig.OledType.ValueType - """ - Override auto-detect in screen - """ - displaymode: global___Config.DisplayConfig.DisplayMode.ValueType - """ - Display Mode - """ - heading_bold: builtins.bool - """ - Print first line in pseudo-bold? FALSE is original style, TRUE is bold - """ - wake_on_tap_or_motion: builtins.bool - """ - Should we wake the screen up on accelerometer detected motion or tap - """ - def __init__( - self, - *, - screen_on_secs: builtins.int = ..., - gps_format: global___Config.DisplayConfig.GpsCoordinateFormat.ValueType = ..., - auto_screen_carousel_secs: builtins.int = ..., - compass_north_top: builtins.bool = ..., - flip_screen: builtins.bool = ..., - units: global___Config.DisplayConfig.DisplayUnits.ValueType = ..., - oled: global___Config.DisplayConfig.OledType.ValueType = ..., - displaymode: global___Config.DisplayConfig.DisplayMode.ValueType = ..., - heading_bold: builtins.bool = ..., - wake_on_tap_or_motion: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "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", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... - - @typing_extensions.final - class LoRaConfig(google.protobuf.message.Message): - """ - Lora Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _RegionCode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _RegionCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.LoRaConfig._RegionCode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: Config.LoRaConfig._RegionCode.ValueType # 0 - """ - Region is not set - """ - US: Config.LoRaConfig._RegionCode.ValueType # 1 - """ - United States - """ - EU_433: Config.LoRaConfig._RegionCode.ValueType # 2 - """ - European Union 433mhz - """ - EU_868: Config.LoRaConfig._RegionCode.ValueType # 3 - """ - European Union 868mhz - """ - CN: Config.LoRaConfig._RegionCode.ValueType # 4 - """ - China - """ - JP: Config.LoRaConfig._RegionCode.ValueType # 5 - """ - Japan - """ - ANZ: Config.LoRaConfig._RegionCode.ValueType # 6 - """ - Australia / New Zealand - """ - KR: Config.LoRaConfig._RegionCode.ValueType # 7 - """ - Korea - """ - TW: Config.LoRaConfig._RegionCode.ValueType # 8 - """ - Taiwan - """ - RU: Config.LoRaConfig._RegionCode.ValueType # 9 - """ - Russia - """ - IN: Config.LoRaConfig._RegionCode.ValueType # 10 - """ - India - """ - NZ_865: Config.LoRaConfig._RegionCode.ValueType # 11 - """ - New Zealand 865mhz - """ - TH: Config.LoRaConfig._RegionCode.ValueType # 12 - """ - Thailand - """ - LORA_24: Config.LoRaConfig._RegionCode.ValueType # 13 - """ - WLAN Band - """ - UA_433: Config.LoRaConfig._RegionCode.ValueType # 14 - """ - Ukraine 433mhz - """ - UA_868: Config.LoRaConfig._RegionCode.ValueType # 15 - """ - Ukraine 868mhz - """ - MY_433: Config.LoRaConfig._RegionCode.ValueType # 16 - """ - Malaysia 433mhz - """ - MY_919: Config.LoRaConfig._RegionCode.ValueType # 17 - """ - Malaysia 919mhz - """ - SG_923: Config.LoRaConfig._RegionCode.ValueType # 18 - """ - Singapore 923mhz - """ - - class RegionCode(_RegionCode, metaclass=_RegionCodeEnumTypeWrapper): ... - UNSET: Config.LoRaConfig.RegionCode.ValueType # 0 - """ - Region is not set - """ - US: Config.LoRaConfig.RegionCode.ValueType # 1 - """ - United States - """ - EU_433: Config.LoRaConfig.RegionCode.ValueType # 2 - """ - European Union 433mhz - """ - EU_868: Config.LoRaConfig.RegionCode.ValueType # 3 - """ - European Union 868mhz - """ - CN: Config.LoRaConfig.RegionCode.ValueType # 4 - """ - China - """ - JP: Config.LoRaConfig.RegionCode.ValueType # 5 - """ - Japan - """ - ANZ: Config.LoRaConfig.RegionCode.ValueType # 6 - """ - Australia / New Zealand - """ - KR: Config.LoRaConfig.RegionCode.ValueType # 7 - """ - Korea - """ - TW: Config.LoRaConfig.RegionCode.ValueType # 8 - """ - Taiwan - """ - RU: Config.LoRaConfig.RegionCode.ValueType # 9 - """ - Russia - """ - IN: Config.LoRaConfig.RegionCode.ValueType # 10 - """ - India - """ - NZ_865: Config.LoRaConfig.RegionCode.ValueType # 11 - """ - New Zealand 865mhz - """ - TH: Config.LoRaConfig.RegionCode.ValueType # 12 - """ - Thailand - """ - LORA_24: Config.LoRaConfig.RegionCode.ValueType # 13 - """ - WLAN Band - """ - UA_433: Config.LoRaConfig.RegionCode.ValueType # 14 - """ - Ukraine 433mhz - """ - UA_868: Config.LoRaConfig.RegionCode.ValueType # 15 - """ - Ukraine 868mhz - """ - MY_433: Config.LoRaConfig.RegionCode.ValueType # 16 - """ - Malaysia 433mhz - """ - MY_919: Config.LoRaConfig.RegionCode.ValueType # 17 - """ - Malaysia 919mhz - """ - SG_923: Config.LoRaConfig.RegionCode.ValueType # 18 - """ - Singapore 923mhz - """ - - class _ModemPreset: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _ModemPresetEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.LoRaConfig._ModemPreset.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - LONG_FAST: Config.LoRaConfig._ModemPreset.ValueType # 0 - """ - Long Range - Fast - """ - LONG_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 1 - """ - Long Range - Slow - """ - VERY_LONG_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 2 - """ - Very Long Range - Slow - """ - MEDIUM_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 3 - """ - Medium Range - Slow - """ - MEDIUM_FAST: Config.LoRaConfig._ModemPreset.ValueType # 4 - """ - Medium Range - Fast - """ - SHORT_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 5 - """ - Short Range - Slow - """ - SHORT_FAST: Config.LoRaConfig._ModemPreset.ValueType # 6 - """ - Short Range - Fast - """ - LONG_MODERATE: Config.LoRaConfig._ModemPreset.ValueType # 7 - """ - Long Range - Moderately Fast - """ - - class ModemPreset(_ModemPreset, metaclass=_ModemPresetEnumTypeWrapper): - """ - Standard predefined channel settings - Note: these mappings must match ModemPreset Choice in the device code. - """ - - LONG_FAST: Config.LoRaConfig.ModemPreset.ValueType # 0 - """ - Long Range - Fast - """ - LONG_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 1 - """ - Long Range - Slow - """ - VERY_LONG_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 2 - """ - Very Long Range - Slow - """ - MEDIUM_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 3 - """ - Medium Range - Slow - """ - MEDIUM_FAST: Config.LoRaConfig.ModemPreset.ValueType # 4 - """ - Medium Range - Fast - """ - SHORT_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 5 - """ - Short Range - Slow - """ - SHORT_FAST: Config.LoRaConfig.ModemPreset.ValueType # 6 - """ - Short Range - Fast - """ - LONG_MODERATE: Config.LoRaConfig.ModemPreset.ValueType # 7 - """ - Long Range - Moderately Fast - """ - - USE_PRESET_FIELD_NUMBER: builtins.int - MODEM_PRESET_FIELD_NUMBER: builtins.int - BANDWIDTH_FIELD_NUMBER: builtins.int - SPREAD_FACTOR_FIELD_NUMBER: builtins.int - CODING_RATE_FIELD_NUMBER: builtins.int - FREQUENCY_OFFSET_FIELD_NUMBER: builtins.int - REGION_FIELD_NUMBER: builtins.int - HOP_LIMIT_FIELD_NUMBER: builtins.int - TX_ENABLED_FIELD_NUMBER: builtins.int - TX_POWER_FIELD_NUMBER: builtins.int - CHANNEL_NUM_FIELD_NUMBER: builtins.int - OVERRIDE_DUTY_CYCLE_FIELD_NUMBER: builtins.int - SX126X_RX_BOOSTED_GAIN_FIELD_NUMBER: builtins.int - OVERRIDE_FREQUENCY_FIELD_NUMBER: builtins.int - IGNORE_INCOMING_FIELD_NUMBER: builtins.int - IGNORE_MQTT_FIELD_NUMBER: builtins.int - use_preset: builtins.bool - """ - When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` - will be taked from their respective manually defined fields - """ - modem_preset: global___Config.LoRaConfig.ModemPreset.ValueType - """ - Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. - As a heuristic: If bandwidth is specified, do not use modem_config. - Because protobufs take ZERO space when the value is zero this works out nicely. - This value is replaced by bandwidth/spread_factor/coding_rate. - If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. - """ - bandwidth: builtins.int - """ - Bandwidth in MHz - Certain bandwidth numbers are 'special' and will be converted to the - appropriate floating point value: 31 -> 31.25MHz - """ - spread_factor: builtins.int - """ - A number from 7 to 12. - Indicates number of chirps per symbol as 1< 7 results in the default - """ - tx_enabled: builtins.bool - """ - Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests. - Defaults to false - """ - tx_power: builtins.int - """ - If zero, then use default max legal continuous power (ie. something that won't - burn out the radio hardware) - In most cases you should use zero here. - Units are in dBm. - """ - channel_num: builtins.int - """ - This controls the actual hardware frequency the radio transmits on. - Most users should never need to be exposed to this field/concept. - A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region). - If ZERO then the rule is "use the old channel name hash based - algorithm to derive the channel number") - If using the hash algorithm the channel number will be: hash(channel_name) % - NUM_CHANNELS (Where num channels depends on the regulatory region). - """ - override_duty_cycle: builtins.bool - """ - If true, duty cycle limits will be exceeded and thus you're possibly not following - the local regulations if you're not a HAM. - Has no effect if the duty cycle of the used region is 100%. - """ - sx126x_rx_boosted_gain: builtins.bool - """ - If true, sets RX boosted gain mode on SX126X based radios - """ - override_frequency: builtins.float - """ - This parameter is for advanced users and licensed HAM radio operators. - Ignore Channel Calculation and use this frequency instead. The frequency_offset - will still be applied. This will allow you to use out-of-band frequencies. - Please respect your local laws and regulations. If you are a HAM, make sure you - enable HAM mode and turn off encryption. - """ - @property - def ignore_incoming(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """ - For testing it is useful sometimes to force a node to never listen to - particular other nodes (simulating radio out of range). All nodenums listed - in ignore_incoming will have packets they send dropped on receive (by router.cpp) - """ - ignore_mqtt: builtins.bool - """ - If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. - """ - def __init__( - self, - *, - use_preset: builtins.bool = ..., - modem_preset: global___Config.LoRaConfig.ModemPreset.ValueType = ..., - bandwidth: builtins.int = ..., - spread_factor: builtins.int = ..., - coding_rate: builtins.int = ..., - frequency_offset: builtins.float = ..., - region: global___Config.LoRaConfig.RegionCode.ValueType = ..., - hop_limit: builtins.int = ..., - tx_enabled: builtins.bool = ..., - tx_power: builtins.int = ..., - channel_num: builtins.int = ..., - override_duty_cycle: builtins.bool = ..., - sx126x_rx_boosted_gain: builtins.bool = ..., - override_frequency: builtins.float = ..., - ignore_incoming: collections.abc.Iterable[builtins.int] | None = ..., - ignore_mqtt: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... - - @typing_extensions.final - class BluetoothConfig(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _PairingMode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _PairingModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.BluetoothConfig._PairingMode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - RANDOM_PIN: Config.BluetoothConfig._PairingMode.ValueType # 0 - """ - Device generates a random PIN that will be shown on the screen of the device for pairing - """ - FIXED_PIN: Config.BluetoothConfig._PairingMode.ValueType # 1 - """ - Device requires a specified fixed PIN for pairing - """ - NO_PIN: Config.BluetoothConfig._PairingMode.ValueType # 2 - """ - Device requires no PIN for pairing - """ - - class PairingMode(_PairingMode, metaclass=_PairingModeEnumTypeWrapper): ... - RANDOM_PIN: Config.BluetoothConfig.PairingMode.ValueType # 0 - """ - Device generates a random PIN that will be shown on the screen of the device for pairing - """ - FIXED_PIN: Config.BluetoothConfig.PairingMode.ValueType # 1 - """ - Device requires a specified fixed PIN for pairing - """ - NO_PIN: Config.BluetoothConfig.PairingMode.ValueType # 2 - """ - Device requires no PIN for pairing - """ - - ENABLED_FIELD_NUMBER: builtins.int - MODE_FIELD_NUMBER: builtins.int - FIXED_PIN_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Enable Bluetooth on the device - """ - mode: global___Config.BluetoothConfig.PairingMode.ValueType - """ - Determines the pairing strategy for the device - """ - fixed_pin: builtins.int - """ - Specified PIN for PairingMode.FixedPin - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - mode: global___Config.BluetoothConfig.PairingMode.ValueType = ..., - fixed_pin: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... - - DEVICE_FIELD_NUMBER: builtins.int - POSITION_FIELD_NUMBER: builtins.int - POWER_FIELD_NUMBER: builtins.int - NETWORK_FIELD_NUMBER: builtins.int - DISPLAY_FIELD_NUMBER: builtins.int - LORA_FIELD_NUMBER: builtins.int - BLUETOOTH_FIELD_NUMBER: builtins.int - @property - def device(self) -> global___Config.DeviceConfig: ... - @property - def position(self) -> global___Config.PositionConfig: ... - @property - def power(self) -> global___Config.PowerConfig: ... - @property - def network(self) -> global___Config.NetworkConfig: ... - @property - def display(self) -> global___Config.DisplayConfig: ... - @property - def lora(self) -> global___Config.LoRaConfig: ... - @property - def bluetooth(self) -> global___Config.BluetoothConfig: ... - def __init__( - self, - *, - device: global___Config.DeviceConfig | None = ..., - position: global___Config.PositionConfig | None = ..., - power: global___Config.PowerConfig | None = ..., - network: global___Config.NetworkConfig | None = ..., - display: global___Config.DisplayConfig | None = ..., - lora: global___Config.LoRaConfig | None = ..., - bluetooth: global___Config.BluetoothConfig | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["device", "position", "power", "network", "display", "lora", "bluetooth"] | None: ... - -global___Config = Config diff --git a/meshtastic/connection_status_pb2.py b/meshtastic/connection_status_pb2.py deleted file mode 100644 index 1d37189..0000000 --- a/meshtastic/connection_status_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/connection_status.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/connection_status.proto\x12\nmeshtastic\"\xb1\x02\n\x16\x44\x65viceConnectionStatus\x12\x33\n\x04wifi\x18\x01 \x01(\x0b\x32 .meshtastic.WifiConnectionStatusH\x00\x88\x01\x01\x12;\n\x08\x65thernet\x18\x02 \x01(\x0b\x32$.meshtastic.EthernetConnectionStatusH\x01\x88\x01\x01\x12=\n\tbluetooth\x18\x03 \x01(\x0b\x32%.meshtastic.BluetoothConnectionStatusH\x02\x88\x01\x01\x12\x37\n\x06serial\x18\x04 \x01(\x0b\x32\".meshtastic.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"g\n\x14WifiConnectionStatus\x12\x33\n\x06status\x18\x01 \x01(\x0b\x32#.meshtastic.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"O\n\x18\x45thernetConnectionStatus\x12\x33\n\x06status\x18\x01 \x01(\x0b\x32#.meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.connection_status_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _DEVICECONNECTIONSTATUS._serialized_start=51 - _DEVICECONNECTIONSTATUS._serialized_end=356 - _WIFICONNECTIONSTATUS._serialized_start=358 - _WIFICONNECTIONSTATUS._serialized_end=461 - _ETHERNETCONNECTIONSTATUS._serialized_start=463 - _ETHERNETCONNECTIONSTATUS._serialized_end=542 - _NETWORKCONNECTIONSTATUS._serialized_start=544 - _NETWORKCONNECTIONSTATUS._serialized_end=667 - _BLUETOOTHCONNECTIONSTATUS._serialized_start=669 - _BLUETOOTHCONNECTIONSTATUS._serialized_end=745 - _SERIALCONNECTIONSTATUS._serialized_start=747 - _SERIALCONNECTIONSTATUS._serialized_end=807 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/connection_status_pb2.pyi b/meshtastic/connection_status_pb2.pyi deleted file mode 100644 index 1e56ba3..0000000 --- a/meshtastic/connection_status_pb2.pyi +++ /dev/null @@ -1,227 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import sys -import typing - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class DeviceConnectionStatus(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - WIFI_FIELD_NUMBER: builtins.int - ETHERNET_FIELD_NUMBER: builtins.int - BLUETOOTH_FIELD_NUMBER: builtins.int - SERIAL_FIELD_NUMBER: builtins.int - @property - def wifi(self) -> global___WifiConnectionStatus: - """ - WiFi Status - """ - @property - def ethernet(self) -> global___EthernetConnectionStatus: - """ - WiFi Status - """ - @property - def bluetooth(self) -> global___BluetoothConnectionStatus: - """ - Bluetooth Status - """ - @property - def serial(self) -> global___SerialConnectionStatus: - """ - Serial Status - """ - def __init__( - self, - *, - wifi: global___WifiConnectionStatus | None = ..., - ethernet: global___EthernetConnectionStatus | None = ..., - bluetooth: global___BluetoothConnectionStatus | None = ..., - serial: global___SerialConnectionStatus | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_bluetooth", b"_bluetooth"]) -> typing_extensions.Literal["bluetooth"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_ethernet", b"_ethernet"]) -> typing_extensions.Literal["ethernet"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_serial", b"_serial"]) -> typing_extensions.Literal["serial"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_wifi", b"_wifi"]) -> typing_extensions.Literal["wifi"] | None: ... - -global___DeviceConnectionStatus = DeviceConnectionStatus - -@typing_extensions.final -class WifiConnectionStatus(google.protobuf.message.Message): - """ - WiFi connection status - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - STATUS_FIELD_NUMBER: builtins.int - SSID_FIELD_NUMBER: builtins.int - RSSI_FIELD_NUMBER: builtins.int - @property - def status(self) -> global___NetworkConnectionStatus: - """ - Connection status - """ - ssid: builtins.str - """ - WiFi access point SSID - """ - rssi: builtins.int - """ - RSSI of wireless connection - """ - def __init__( - self, - *, - status: global___NetworkConnectionStatus | None = ..., - ssid: builtins.str = ..., - rssi: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["status", b"status"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["rssi", b"rssi", "ssid", b"ssid", "status", b"status"]) -> None: ... - -global___WifiConnectionStatus = WifiConnectionStatus - -@typing_extensions.final -class EthernetConnectionStatus(google.protobuf.message.Message): - """ - Ethernet connection status - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - STATUS_FIELD_NUMBER: builtins.int - @property - def status(self) -> global___NetworkConnectionStatus: - """ - Connection status - """ - def __init__( - self, - *, - status: global___NetworkConnectionStatus | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["status", b"status"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["status", b"status"]) -> None: ... - -global___EthernetConnectionStatus = EthernetConnectionStatus - -@typing_extensions.final -class NetworkConnectionStatus(google.protobuf.message.Message): - """ - Ethernet or WiFi connection status - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - IP_ADDRESS_FIELD_NUMBER: builtins.int - IS_CONNECTED_FIELD_NUMBER: builtins.int - IS_MQTT_CONNECTED_FIELD_NUMBER: builtins.int - IS_SYSLOG_CONNECTED_FIELD_NUMBER: builtins.int - ip_address: builtins.int - """ - IP address of device - """ - is_connected: builtins.bool - """ - Whether the device has an active connection or not - """ - is_mqtt_connected: builtins.bool - """ - Whether the device has an active connection to an MQTT broker or not - """ - is_syslog_connected: builtins.bool - """ - Whether the device is actively remote syslogging or not - """ - def __init__( - self, - *, - ip_address: builtins.int = ..., - is_connected: builtins.bool = ..., - is_mqtt_connected: builtins.bool = ..., - is_syslog_connected: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["ip_address", b"ip_address", "is_connected", b"is_connected", "is_mqtt_connected", b"is_mqtt_connected", "is_syslog_connected", b"is_syslog_connected"]) -> None: ... - -global___NetworkConnectionStatus = NetworkConnectionStatus - -@typing_extensions.final -class BluetoothConnectionStatus(google.protobuf.message.Message): - """ - Bluetooth connection status - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PIN_FIELD_NUMBER: builtins.int - RSSI_FIELD_NUMBER: builtins.int - IS_CONNECTED_FIELD_NUMBER: builtins.int - pin: builtins.int - """ - The pairing PIN for bluetooth - """ - rssi: builtins.int - """ - RSSI of bluetooth connection - """ - is_connected: builtins.bool - """ - Whether the device has an active connection or not - """ - def __init__( - self, - *, - pin: builtins.int = ..., - rssi: builtins.int = ..., - is_connected: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["is_connected", b"is_connected", "pin", b"pin", "rssi", b"rssi"]) -> None: ... - -global___BluetoothConnectionStatus = BluetoothConnectionStatus - -@typing_extensions.final -class SerialConnectionStatus(google.protobuf.message.Message): - """ - Serial connection status - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - BAUD_FIELD_NUMBER: builtins.int - IS_CONNECTED_FIELD_NUMBER: builtins.int - baud: builtins.int - """ - Serial baud rate - """ - is_connected: builtins.bool - """ - Whether the device has an active connection or not - """ - def __init__( - self, - *, - baud: builtins.int = ..., - is_connected: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["baud", b"baud", "is_connected", b"is_connected"]) -> None: ... - -global___SerialConnectionStatus = SerialConnectionStatus diff --git a/meshtastic/deviceonly_pb2.py b/meshtastic/deviceonly_pb2.py deleted file mode 100644 index 02dc0f8..0000000 --- a/meshtastic/deviceonly_pb2.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/deviceonly.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2 -from meshtastic import localonly_pb2 as meshtastic_dot_localonly__pb2 -from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2 -from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 -from meshtastic import telemetry_pb2 as meshtastic_dot_telemetry__pb2 -from . import nanopb_pb2 as nanopb__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x12\nmeshtastic\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x0cnanopb.proto\"\x90\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\x37\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x1e.meshtastic.Position.LocSource\"\x86\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1e\n\x04user\x18\x02 \x01(\x0b\x32\x10.meshtastic.User\x12*\n\x08position\x18\x03 \x01(\x0b\x32\x18.meshtastic.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12\x31\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x19.meshtastic.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\xc3\x03\n\x0b\x44\x65viceState\x12\'\n\x07my_node\x18\x02 \x01(\x0b\x32\x16.meshtastic.MyNodeInfo\x12\x1f\n\x05owner\x18\x03 \x01(\x0b\x32\x10.meshtastic.User\x12-\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x16.meshtastic.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12/\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x16.meshtastic.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12+\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x16.meshtastic.MeshPacket\x12\x44\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32!.meshtastic.NodeRemoteHardwarePin\x12Z\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32\x18.meshtastic.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"E\n\x0b\x43hannelFile\x12%\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x13.meshtastic.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x97\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12)\n\x08oem_font\x18\x04 \x01(\x0e\x32\x17.meshtastic.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12\x31\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x17.meshtastic.LocalConfig\x12>\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x1d.meshtastic.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.deviceonly_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010' - _DEVICESTATE.fields_by_name['no_save']._options = None - _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' - _DEVICESTATE.fields_by_name['node_db_lite']._options = None - _DEVICESTATE.fields_by_name['node_db_lite']._serialized_options = b'\222?\'\222\001$std::vector' - _SCREENFONTS._serialized_start=1413 - _SCREENFONTS._serialized_end=1475 - _POSITIONLITE._serialized_start=195 - _POSITIONLITE._serialized_end=339 - _NODEINFOLITE._serialized_start=342 - _NODEINFOLITE._serialized_end=604 - _DEVICESTATE._serialized_start=607 - _DEVICESTATE._serialized_end=1058 - _CHANNELFILE._serialized_start=1060 - _CHANNELFILE._serialized_end=1129 - _OEMSTORE._serialized_start=1132 - _OEMSTORE._serialized_end=1411 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/deviceonly_pb2.pyi b/meshtastic/deviceonly_pb2.pyi deleted file mode 100644 index 38e8b9f..0000000 --- a/meshtastic/deviceonly_pb2.pyi +++ /dev/null @@ -1,386 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import meshtastic.channel_pb2 -import meshtastic.localonly_pb2 -import meshtastic.mesh_pb2 -import meshtastic.telemetry_pb2 -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 _ScreenFonts: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _ScreenFontsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ScreenFonts.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - FONT_SMALL: _ScreenFonts.ValueType # 0 - """ - TODO: REPLACE - """ - FONT_MEDIUM: _ScreenFonts.ValueType # 1 - """ - TODO: REPLACE - """ - FONT_LARGE: _ScreenFonts.ValueType # 2 - """ - TODO: REPLACE - """ - -class ScreenFonts(_ScreenFonts, metaclass=_ScreenFontsEnumTypeWrapper): - """ - Font sizes for the device screen - """ - -FONT_SMALL: ScreenFonts.ValueType # 0 -""" -TODO: REPLACE -""" -FONT_MEDIUM: ScreenFonts.ValueType # 1 -""" -TODO: REPLACE -""" -FONT_LARGE: ScreenFonts.ValueType # 2 -""" -TODO: REPLACE -""" -global___ScreenFonts = ScreenFonts - -@typing_extensions.final -class PositionLite(google.protobuf.message.Message): - """ - Position with static location information only for NodeDBLite - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LATITUDE_I_FIELD_NUMBER: builtins.int - LONGITUDE_I_FIELD_NUMBER: builtins.int - ALTITUDE_FIELD_NUMBER: builtins.int - TIME_FIELD_NUMBER: builtins.int - LOCATION_SOURCE_FIELD_NUMBER: builtins.int - latitude_i: builtins.int - """ - The new preferred location encoding, multiply by 1e-7 to get degrees - in floating point - """ - longitude_i: builtins.int - """ - TODO: REPLACE - """ - altitude: builtins.int - """ - In meters above MSL (but see issue #359) - """ - time: builtins.int - """ - This is usually not sent over the mesh (to save space), but it is sent - from the phone so that the local device can set its RTC If it is sent over - the mesh (because there are devices on the mesh without GPS), it will only - be sent by devices which has a hardware GPS clock. - seconds since 1970 - """ - location_source: meshtastic.mesh_pb2.Position.LocSource.ValueType - """ - TODO: REPLACE - """ - def __init__( - self, - *, - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - altitude: builtins.int = ..., - time: builtins.int = ..., - location_source: meshtastic.mesh_pb2.Position.LocSource.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["altitude", b"altitude", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "time", b"time"]) -> None: ... - -global___PositionLite = PositionLite - -@typing_extensions.final -class NodeInfoLite(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NUM_FIELD_NUMBER: builtins.int - USER_FIELD_NUMBER: builtins.int - POSITION_FIELD_NUMBER: builtins.int - SNR_FIELD_NUMBER: builtins.int - LAST_HEARD_FIELD_NUMBER: builtins.int - DEVICE_METRICS_FIELD_NUMBER: builtins.int - CHANNEL_FIELD_NUMBER: builtins.int - VIA_MQTT_FIELD_NUMBER: builtins.int - HOPS_AWAY_FIELD_NUMBER: builtins.int - IS_FAVORITE_FIELD_NUMBER: builtins.int - num: builtins.int - """ - The node number - """ - @property - def user(self) -> meshtastic.mesh_pb2.User: - """ - The user info for this node - """ - @property - def position(self) -> global___PositionLite: - """ - This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. - Position.time now indicates the last time we received a POSITION from that node. - """ - snr: builtins.float - """ - Returns the Signal-to-noise ratio (SNR) of the last received message, - as measured by the receiver. Return SNR of the last received message in dB - """ - last_heard: builtins.int - """ - Set to indicate the last time we received a packet from this node - """ - @property - def device_metrics(self) -> meshtastic.telemetry_pb2.DeviceMetrics: - """ - The latest device metrics for the node. - """ - channel: builtins.int - """ - local channel index we heard that node on. Only populated if its not the default channel. - """ - via_mqtt: builtins.bool - """ - True if we witnessed the node over MQTT instead of LoRA transport - """ - hops_away: builtins.int - """ - Number of hops away from us this node is (0 if adjacent) - """ - is_favorite: builtins.bool - """ - True if node is in our favorites list - Persists between NodeDB internal clean ups - """ - def __init__( - self, - *, - num: builtins.int = ..., - user: meshtastic.mesh_pb2.User | None = ..., - position: global___PositionLite | None = ..., - snr: builtins.float = ..., - last_heard: builtins.int = ..., - device_metrics: meshtastic.telemetry_pb2.DeviceMetrics | None = ..., - channel: builtins.int = ..., - via_mqtt: builtins.bool = ..., - hops_away: builtins.int = ..., - is_favorite: builtins.bool = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ... - -global___NodeInfoLite = NodeInfoLite - -@typing_extensions.final -class DeviceState(google.protobuf.message.Message): - """ - This message is never sent over the wire, but it is used for serializing DB - state to flash in the device code - FIXME, since we write this each time we enter deep sleep (and have infinite - flash) it would be better to use some sort of append only data structure for - the receive queue and use the preferences store for the other stuff - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MY_NODE_FIELD_NUMBER: builtins.int - OWNER_FIELD_NUMBER: builtins.int - RECEIVE_QUEUE_FIELD_NUMBER: builtins.int - VERSION_FIELD_NUMBER: builtins.int - RX_TEXT_MESSAGE_FIELD_NUMBER: builtins.int - NO_SAVE_FIELD_NUMBER: builtins.int - DID_GPS_RESET_FIELD_NUMBER: builtins.int - RX_WAYPOINT_FIELD_NUMBER: builtins.int - NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: builtins.int - NODE_DB_LITE_FIELD_NUMBER: builtins.int - @property - def my_node(self) -> meshtastic.mesh_pb2.MyNodeInfo: - """ - Read only settings/info about this node - """ - @property - def owner(self) -> meshtastic.mesh_pb2.User: - """ - My owner info - """ - @property - def receive_queue(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.mesh_pb2.MeshPacket]: - """ - Received packets saved for delivery to the phone - """ - version: builtins.int - """ - A version integer used to invalidate old save files when we make - incompatible changes This integer is set at build time and is private to - NodeDB.cpp in the device code. - """ - @property - def rx_text_message(self) -> meshtastic.mesh_pb2.MeshPacket: - """ - We keep the last received text message (only) stored in the device flash, - so we can show it on the screen. - Might be null - """ - no_save: builtins.bool - """ - Used only during development. - Indicates developer is testing and changes should never be saved to flash. - Deprecated in 2.3.1 - """ - did_gps_reset: builtins.bool - """ - Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. - """ - @property - def rx_waypoint(self) -> meshtastic.mesh_pb2.MeshPacket: - """ - We keep the last received waypoint stored in the device flash, - so we can show it on the screen. - Might be null - """ - @property - def node_remote_hardware_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.mesh_pb2.NodeRemoteHardwarePin]: - """ - The mesh's nodes with their available gpio pins for RemoteHardware module - """ - @property - def node_db_lite(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NodeInfoLite]: - """ - New lite version of NodeDB to decrease memory footprint - """ - def __init__( - self, - *, - my_node: meshtastic.mesh_pb2.MyNodeInfo | None = ..., - owner: meshtastic.mesh_pb2.User | None = ..., - receive_queue: collections.abc.Iterable[meshtastic.mesh_pb2.MeshPacket] | None = ..., - version: builtins.int = ..., - rx_text_message: meshtastic.mesh_pb2.MeshPacket | None = ..., - no_save: builtins.bool = ..., - did_gps_reset: builtins.bool = ..., - rx_waypoint: meshtastic.mesh_pb2.MeshPacket | None = ..., - node_remote_hardware_pins: collections.abc.Iterable[meshtastic.mesh_pb2.NodeRemoteHardwarePin] | None = ..., - node_db_lite: collections.abc.Iterable[global___NodeInfoLite] | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["my_node", b"my_node", "owner", b"owner", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["did_gps_reset", b"did_gps_reset", "my_node", b"my_node", "no_save", b"no_save", "node_db_lite", b"node_db_lite", "node_remote_hardware_pins", b"node_remote_hardware_pins", "owner", b"owner", "receive_queue", b"receive_queue", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint", "version", b"version"]) -> None: ... - -global___DeviceState = DeviceState - -@typing_extensions.final -class ChannelFile(google.protobuf.message.Message): - """ - The on-disk saved channels - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CHANNELS_FIELD_NUMBER: builtins.int - VERSION_FIELD_NUMBER: builtins.int - @property - def channels(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.channel_pb2.Channel]: - """ - The channels our node knows about - """ - version: builtins.int - """ - A version integer used to invalidate old save files when we make - incompatible changes This integer is set at build time and is private to - NodeDB.cpp in the device code. - """ - def __init__( - self, - *, - channels: collections.abc.Iterable[meshtastic.channel_pb2.Channel] | None = ..., - version: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["channels", b"channels", "version", b"version"]) -> None: ... - -global___ChannelFile = ChannelFile - -@typing_extensions.final -class OEMStore(google.protobuf.message.Message): - """ - This can be used for customizing the firmware distribution. If populated, - show a secondary bootup screen with custom logo and text for 2.5 seconds. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - OEM_ICON_WIDTH_FIELD_NUMBER: builtins.int - OEM_ICON_HEIGHT_FIELD_NUMBER: builtins.int - OEM_ICON_BITS_FIELD_NUMBER: builtins.int - OEM_FONT_FIELD_NUMBER: builtins.int - OEM_TEXT_FIELD_NUMBER: builtins.int - OEM_AES_KEY_FIELD_NUMBER: builtins.int - OEM_LOCAL_CONFIG_FIELD_NUMBER: builtins.int - OEM_LOCAL_MODULE_CONFIG_FIELD_NUMBER: builtins.int - oem_icon_width: builtins.int - """ - The Logo width in Px - """ - oem_icon_height: builtins.int - """ - The Logo height in Px - """ - oem_icon_bits: builtins.bytes - """ - The Logo in XBM bytechar format - """ - oem_font: global___ScreenFonts.ValueType - """ - Use this font for the OEM text. - """ - oem_text: builtins.str - """ - Use this font for the OEM text. - """ - oem_aes_key: builtins.bytes - """ - The default device encryption key, 16 or 32 byte - """ - @property - def oem_local_config(self) -> meshtastic.localonly_pb2.LocalConfig: - """ - A Preset LocalConfig to apply during factory reset - """ - @property - def oem_local_module_config(self) -> meshtastic.localonly_pb2.LocalModuleConfig: - """ - A Preset LocalModuleConfig to apply during factory reset - """ - def __init__( - self, - *, - oem_icon_width: builtins.int = ..., - oem_icon_height: builtins.int = ..., - oem_icon_bits: builtins.bytes = ..., - oem_font: global___ScreenFonts.ValueType = ..., - oem_text: builtins.str = ..., - oem_aes_key: builtins.bytes = ..., - oem_local_config: meshtastic.localonly_pb2.LocalConfig | None = ..., - oem_local_module_config: meshtastic.localonly_pb2.LocalModuleConfig | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["oem_local_config", b"oem_local_config", "oem_local_module_config", b"oem_local_module_config"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["oem_aes_key", b"oem_aes_key", "oem_font", b"oem_font", "oem_icon_bits", b"oem_icon_bits", "oem_icon_height", b"oem_icon_height", "oem_icon_width", b"oem_icon_width", "oem_local_config", b"oem_local_config", "oem_local_module_config", b"oem_local_module_config", "oem_text", b"oem_text"]) -> None: ... - -global___OEMStore = OEMStore diff --git a/meshtastic/localonly_pb2.py b/meshtastic/localonly_pb2.py deleted file mode 100644 index 324aaad..0000000 --- a/meshtastic/localonly_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/localonly.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import config_pb2 as meshtastic_dot_config__pb2 -from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ameshtastic/localonly.proto\x12\nmeshtastic\x1a\x17meshtastic/config.proto\x1a\x1emeshtastic/module_config.proto\"\xfd\x02\n\x0bLocalConfig\x12/\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x1f.meshtastic.Config.DeviceConfig\x12\x33\n\x08position\x18\x02 \x01(\x0b\x32!.meshtastic.Config.PositionConfig\x12-\n\x05power\x18\x03 \x01(\x0b\x32\x1e.meshtastic.Config.PowerConfig\x12\x31\n\x07network\x18\x04 \x01(\x0b\x32 .meshtastic.Config.NetworkConfig\x12\x31\n\x07\x64isplay\x18\x05 \x01(\x0b\x32 .meshtastic.Config.DisplayConfig\x12+\n\x04lora\x18\x06 \x01(\x0b\x32\x1d.meshtastic.Config.LoRaConfig\x12\x35\n\tbluetooth\x18\x07 \x01(\x0b\x32\".meshtastic.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\"\xfb\x06\n\x11LocalModuleConfig\x12\x31\n\x04mqtt\x18\x01 \x01(\x0b\x32#.meshtastic.ModuleConfig.MQTTConfig\x12\x35\n\x06serial\x18\x02 \x01(\x0b\x32%.meshtastic.ModuleConfig.SerialConfig\x12R\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32\x33.meshtastic.ModuleConfig.ExternalNotificationConfig\x12\x42\n\rstore_forward\x18\x04 \x01(\x0b\x32+.meshtastic.ModuleConfig.StoreForwardConfig\x12<\n\nrange_test\x18\x05 \x01(\x0b\x32(.meshtastic.ModuleConfig.RangeTestConfig\x12;\n\ttelemetry\x18\x06 \x01(\x0b\x32(.meshtastic.ModuleConfig.TelemetryConfig\x12\x44\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32,.meshtastic.ModuleConfig.CannedMessageConfig\x12\x33\n\x05\x61udio\x18\t \x01(\x0b\x32$.meshtastic.ModuleConfig.AudioConfig\x12\x46\n\x0fremote_hardware\x18\n \x01(\x0b\x32-.meshtastic.ModuleConfig.RemoteHardwareConfig\x12\x42\n\rneighbor_info\x18\x0b \x01(\x0b\x32+.meshtastic.ModuleConfig.NeighborInfoConfig\x12H\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32..meshtastic.ModuleConfig.AmbientLightingConfig\x12H\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32..meshtastic.ModuleConfig.DetectionSensorConfig\x12=\n\npaxcounter\x18\x0e \x01(\x0b\x32).meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.localonly_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _LOCALCONFIG._serialized_start=100 - _LOCALCONFIG._serialized_end=481 - _LOCALMODULECONFIG._serialized_start=484 - _LOCALMODULECONFIG._serialized_end=1375 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/localonly_pb2.pyi b/meshtastic/localonly_pb2.pyi deleted file mode 100644 index 19cdc02..0000000 --- a/meshtastic/localonly_pb2.pyi +++ /dev/null @@ -1,204 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import meshtastic.config_pb2 -import meshtastic.module_config_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class LocalConfig(google.protobuf.message.Message): - """ - Protobuf structures common to apponly.proto and deviceonly.proto - This is never sent over the wire, only for local use - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DEVICE_FIELD_NUMBER: builtins.int - POSITION_FIELD_NUMBER: builtins.int - POWER_FIELD_NUMBER: builtins.int - NETWORK_FIELD_NUMBER: builtins.int - DISPLAY_FIELD_NUMBER: builtins.int - LORA_FIELD_NUMBER: builtins.int - BLUETOOTH_FIELD_NUMBER: builtins.int - VERSION_FIELD_NUMBER: builtins.int - @property - def device(self) -> meshtastic.config_pb2.Config.DeviceConfig: - """ - The part of the config that is specific to the Device - """ - @property - def position(self) -> meshtastic.config_pb2.Config.PositionConfig: - """ - The part of the config that is specific to the GPS Position - """ - @property - def power(self) -> meshtastic.config_pb2.Config.PowerConfig: - """ - The part of the config that is specific to the Power settings - """ - @property - def network(self) -> meshtastic.config_pb2.Config.NetworkConfig: - """ - The part of the config that is specific to the Wifi Settings - """ - @property - def display(self) -> meshtastic.config_pb2.Config.DisplayConfig: - """ - The part of the config that is specific to the Display - """ - @property - def lora(self) -> meshtastic.config_pb2.Config.LoRaConfig: - """ - The part of the config that is specific to the Lora Radio - """ - @property - def bluetooth(self) -> meshtastic.config_pb2.Config.BluetoothConfig: - """ - The part of the config that is specific to the Bluetooth settings - """ - version: builtins.int - """ - A version integer used to invalidate old save files when we make - incompatible changes This integer is set at build time and is private to - NodeDB.cpp in the device code. - """ - def __init__( - self, - *, - device: meshtastic.config_pb2.Config.DeviceConfig | None = ..., - position: meshtastic.config_pb2.Config.PositionConfig | None = ..., - power: meshtastic.config_pb2.Config.PowerConfig | None = ..., - network: meshtastic.config_pb2.Config.NetworkConfig | None = ..., - display: meshtastic.config_pb2.Config.DisplayConfig | None = ..., - lora: meshtastic.config_pb2.Config.LoRaConfig | None = ..., - bluetooth: meshtastic.config_pb2.Config.BluetoothConfig | None = ..., - version: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "version", b"version"]) -> None: ... - -global___LocalConfig = LocalConfig - -@typing_extensions.final -class LocalModuleConfig(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MQTT_FIELD_NUMBER: builtins.int - SERIAL_FIELD_NUMBER: builtins.int - EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int - STORE_FORWARD_FIELD_NUMBER: builtins.int - RANGE_TEST_FIELD_NUMBER: builtins.int - TELEMETRY_FIELD_NUMBER: builtins.int - CANNED_MESSAGE_FIELD_NUMBER: builtins.int - AUDIO_FIELD_NUMBER: builtins.int - REMOTE_HARDWARE_FIELD_NUMBER: builtins.int - NEIGHBOR_INFO_FIELD_NUMBER: builtins.int - AMBIENT_LIGHTING_FIELD_NUMBER: builtins.int - DETECTION_SENSOR_FIELD_NUMBER: builtins.int - PAXCOUNTER_FIELD_NUMBER: builtins.int - VERSION_FIELD_NUMBER: builtins.int - @property - def mqtt(self) -> meshtastic.module_config_pb2.ModuleConfig.MQTTConfig: - """ - The part of the config that is specific to the MQTT module - """ - @property - def serial(self) -> meshtastic.module_config_pb2.ModuleConfig.SerialConfig: - """ - The part of the config that is specific to the Serial module - """ - @property - def external_notification(self) -> meshtastic.module_config_pb2.ModuleConfig.ExternalNotificationConfig: - """ - The part of the config that is specific to the ExternalNotification module - """ - @property - def store_forward(self) -> meshtastic.module_config_pb2.ModuleConfig.StoreForwardConfig: - """ - The part of the config that is specific to the Store & Forward module - """ - @property - def range_test(self) -> meshtastic.module_config_pb2.ModuleConfig.RangeTestConfig: - """ - The part of the config that is specific to the RangeTest module - """ - @property - def telemetry(self) -> meshtastic.module_config_pb2.ModuleConfig.TelemetryConfig: - """ - The part of the config that is specific to the Telemetry module - """ - @property - def canned_message(self) -> meshtastic.module_config_pb2.ModuleConfig.CannedMessageConfig: - """ - The part of the config that is specific to the Canned Message module - """ - @property - def audio(self) -> meshtastic.module_config_pb2.ModuleConfig.AudioConfig: - """ - The part of the config that is specific to the Audio module - """ - @property - def remote_hardware(self) -> meshtastic.module_config_pb2.ModuleConfig.RemoteHardwareConfig: - """ - The part of the config that is specific to the Remote Hardware module - """ - @property - def neighbor_info(self) -> meshtastic.module_config_pb2.ModuleConfig.NeighborInfoConfig: - """ - The part of the config that is specific to the Neighbor Info module - """ - @property - def ambient_lighting(self) -> meshtastic.module_config_pb2.ModuleConfig.AmbientLightingConfig: - """ - The part of the config that is specific to the Ambient Lighting module - """ - @property - def detection_sensor(self) -> meshtastic.module_config_pb2.ModuleConfig.DetectionSensorConfig: - """ - The part of the config that is specific to the Detection Sensor module - """ - @property - def paxcounter(self) -> meshtastic.module_config_pb2.ModuleConfig.PaxcounterConfig: - """ - Paxcounter Config - """ - version: builtins.int - """ - A version integer used to invalidate old save files when we make - incompatible changes This integer is set at build time and is private to - NodeDB.cpp in the device code. - """ - def __init__( - self, - *, - mqtt: meshtastic.module_config_pb2.ModuleConfig.MQTTConfig | None = ..., - serial: meshtastic.module_config_pb2.ModuleConfig.SerialConfig | None = ..., - external_notification: meshtastic.module_config_pb2.ModuleConfig.ExternalNotificationConfig | None = ..., - store_forward: meshtastic.module_config_pb2.ModuleConfig.StoreForwardConfig | None = ..., - range_test: meshtastic.module_config_pb2.ModuleConfig.RangeTestConfig | None = ..., - telemetry: meshtastic.module_config_pb2.ModuleConfig.TelemetryConfig | None = ..., - canned_message: meshtastic.module_config_pb2.ModuleConfig.CannedMessageConfig | None = ..., - audio: meshtastic.module_config_pb2.ModuleConfig.AudioConfig | None = ..., - remote_hardware: meshtastic.module_config_pb2.ModuleConfig.RemoteHardwareConfig | None = ..., - neighbor_info: meshtastic.module_config_pb2.ModuleConfig.NeighborInfoConfig | None = ..., - ambient_lighting: meshtastic.module_config_pb2.ModuleConfig.AmbientLightingConfig | None = ..., - detection_sensor: meshtastic.module_config_pb2.ModuleConfig.DetectionSensorConfig | None = ..., - paxcounter: meshtastic.module_config_pb2.ModuleConfig.PaxcounterConfig | None = ..., - version: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry", "version", b"version"]) -> None: ... - -global___LocalModuleConfig = LocalModuleConfig diff --git a/meshtastic/mesh_pb2.py b/meshtastic/mesh_pb2.py deleted file mode 100644 index 29cfeb2..0000000 --- a/meshtastic/mesh_pb2.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/mesh.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2 -from meshtastic import config_pb2 as meshtastic_dot_config__pb2 -from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 -from meshtastic import portnums_pb2 as meshtastic_dot_portnums__pb2 -from meshtastic import telemetry_pb2 as meshtastic_dot_telemetry__pb2 -from meshtastic import xmodem_pb2 as meshtastic_dot_xmodem__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15meshtastic/mesh.proto\x12\nmeshtastic\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\x1emeshtastic/module_config.proto\x1a\x19meshtastic/portnums.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x17meshtastic/xmodem.proto\"\xe5\x05\n\x08Position\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\x37\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x1e.meshtastic.Position.LocSource\x12\x37\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\x1e.meshtastic.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xc4\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12+\n\x08hw_model\x18\x05 \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12\x32\n\x04role\x18\x07 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\xfc\x02\n\x07Routing\x12\x33\n\rroute_request\x18\x01 \x01(\x0b\x32\x1a.meshtastic.RouteDiscoveryH\x00\x12\x31\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x1a.meshtastic.RouteDiscoveryH\x00\x12\x31\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x19.meshtastic.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xa7\x01\n\x04\x44\x61ta\x12$\n\x07portnum\x18\x01 \x01(\x0e\x32\x13.meshtastic.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\x95\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12#\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x10.meshtastic.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12\x31\n\x08priority\x18\x0b \x01(\x0e\x32\x1f.meshtastic.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12\x33\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\x1e.meshtastic.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\xfe\x01\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1e\n\x04user\x18\x02 \x01(\x0b\x32\x10.meshtastic.User\x12&\n\x08position\x18\x03 \x01(\x0b\x32\x14.meshtastic.Position\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12\x31\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x19.meshtastic.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc0\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12*\n\x05level\x18\x04 \x01(\x0e\x32\x1b.meshtastic.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xdb\x04\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12(\n\x06packet\x18\x02 \x01(\x0b\x32\x16.meshtastic.MeshPacketH\x00\x12)\n\x07my_info\x18\x03 \x01(\x0b\x32\x16.meshtastic.MyNodeInfoH\x00\x12)\n\tnode_info\x18\x04 \x01(\x0b\x32\x14.meshtastic.NodeInfoH\x00\x12$\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x12.meshtastic.ConfigH\x00\x12+\n\nlog_record\x18\x06 \x01(\x0b\x32\x15.meshtastic.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x30\n\x0cmoduleConfig\x18\t \x01(\x0b\x32\x18.meshtastic.ModuleConfigH\x00\x12&\n\x07\x63hannel\x18\n \x01(\x0b\x32\x13.meshtastic.ChannelH\x00\x12.\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32\x17.meshtastic.QueueStatusH\x00\x12*\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x12.meshtastic.XModemH\x00\x12.\n\x08metadata\x18\r \x01(\x0b\x32\x1a.meshtastic.DeviceMetadataH\x00\x12\x44\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32\".meshtastic.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\x94\x02\n\x07ToRadio\x12(\n\x06packet\x18\x01 \x01(\x0b\x32\x16.meshtastic.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12*\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x12.meshtastic.XModemH\x00\x12\x44\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32\".meshtastic.MqttClientProxyMessageH\x00\x12*\n\theartbeat\x18\x07 \x01(\x0b\x32\x15.meshtastic.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"@\n\nCompressed\x12$\n\x07portnum\x18\x01 \x01(\x0e\x32\x13.meshtastic.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x87\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\'\n\tneighbors\x18\x04 \x03(\x0b\x32\x14.meshtastic.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xad\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12\x32\n\x04role\x18\x07 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12+\n\x08hw_model\x18\t \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"U\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12*\n\x03pin\x18\x02 \x01(\x0b\x32\x1d.meshtastic.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xaa\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12\x32\n\rresend_chunks\x18\x04 \x01(\x0b\x32\x19.meshtastic.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xeb\x08\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.mesh_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _USER.fields_by_name['macaddr']._options = None - _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' - _MESHPACKET.fields_by_name['delayed']._options = None - _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _HARDWAREMODEL._serialized_start=5046 - _HARDWAREMODEL._serialized_end=6177 - _CONSTANTS._serialized_start=6179 - _CONSTANTS._serialized_end=6223 - _CRITICALERRORCODE._serialized_start=6226 - _CRITICALERRORCODE._serialized_end=6464 - _POSITION._serialized_start=201 - _POSITION._serialized_end=942 - _POSITION_LOCSOURCE._serialized_start=764 - _POSITION_LOCSOURCE._serialized_end=842 - _POSITION_ALTSOURCE._serialized_start=844 - _POSITION_ALTSOURCE._serialized_end=942 - _USER._serialized_start=945 - _USER._serialized_end=1141 - _ROUTEDISCOVERY._serialized_start=1143 - _ROUTEDISCOVERY._serialized_end=1174 - _ROUTING._serialized_start=1177 - _ROUTING._serialized_end=1557 - _ROUTING_ERROR._serialized_start=1344 - _ROUTING_ERROR._serialized_end=1546 - _DATA._serialized_start=1560 - _DATA._serialized_end=1727 - _WAYPOINT._serialized_start=1730 - _WAYPOINT._serialized_end=1877 - _MQTTCLIENTPROXYMESSAGE._serialized_start=1879 - _MQTTCLIENTPROXYMESSAGE._serialized_end=1987 - _MESHPACKET._serialized_start=1990 - _MESHPACKET._serialized_end=2523 - _MESHPACKET_PRIORITY._serialized_start=2345 - _MESHPACKET_PRIORITY._serialized_end=2436 - _MESHPACKET_DELAYED._serialized_start=2438 - _MESHPACKET_DELAYED._serialized_end=2504 - _NODEINFO._serialized_start=2526 - _NODEINFO._serialized_end=2780 - _MYNODEINFO._serialized_start=2782 - _MYNODEINFO._serialized_end=2862 - _LOGRECORD._serialized_start=2865 - _LOGRECORD._serialized_end=3057 - _LOGRECORD_LEVEL._serialized_start=2969 - _LOGRECORD_LEVEL._serialized_end=3057 - _QUEUESTATUS._serialized_start=3059 - _QUEUESTATUS._serialized_end=3139 - _FROMRADIO._serialized_start=3142 - _FROMRADIO._serialized_end=3745 - _TORADIO._serialized_start=3748 - _TORADIO._serialized_end=4024 - _COMPRESSED._serialized_start=4026 - _COMPRESSED._serialized_end=4090 - _NEIGHBORINFO._serialized_start=4093 - _NEIGHBORINFO._serialized_end=4228 - _NEIGHBOR._serialized_start=4230 - _NEIGHBOR._serialized_end=4330 - _DEVICEMETADATA._serialized_start=4333 - _DEVICEMETADATA._serialized_end=4634 - _HEARTBEAT._serialized_start=4636 - _HEARTBEAT._serialized_end=4647 - _NODEREMOTEHARDWAREPIN._serialized_start=4649 - _NODEREMOTEHARDWAREPIN._serialized_end=4734 - _CHUNKEDPAYLOAD._serialized_start=4736 - _CHUNKEDPAYLOAD._serialized_end=4837 - _RESEND_CHUNKS._serialized_start=4839 - _RESEND_CHUNKS._serialized_end=4870 - _CHUNKEDPAYLOADRESPONSE._serialized_start=4873 - _CHUNKEDPAYLOADRESPONSE._serialized_end=5043 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/mesh_pb2.pyi b/meshtastic/mesh_pb2.pyi deleted file mode 100644 index 391aae7..0000000 --- a/meshtastic/mesh_pb2.pyi +++ /dev/null @@ -1,2526 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import meshtastic.channel_pb2 -import meshtastic.config_pb2 -import meshtastic.module_config_pb2 -import meshtastic.portnums_pb2 -import meshtastic.telemetry_pb2 -import meshtastic.xmodem_pb2 -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 _HardwareModel: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_HardwareModel.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: _HardwareModel.ValueType # 0 - """ - TODO: REPLACE - """ - TLORA_V2: _HardwareModel.ValueType # 1 - """ - TODO: REPLACE - """ - TLORA_V1: _HardwareModel.ValueType # 2 - """ - TODO: REPLACE - """ - TLORA_V2_1_1P6: _HardwareModel.ValueType # 3 - """ - TODO: REPLACE - """ - TBEAM: _HardwareModel.ValueType # 4 - """ - TODO: REPLACE - """ - HELTEC_V2_0: _HardwareModel.ValueType # 5 - """ - The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 - (see HELTEC_V2 for the new version). - """ - TBEAM_V0P7: _HardwareModel.ValueType # 6 - """ - TODO: REPLACE - """ - T_ECHO: _HardwareModel.ValueType # 7 - """ - TODO: REPLACE - """ - TLORA_V1_1P3: _HardwareModel.ValueType # 8 - """ - TODO: REPLACE - """ - RAK4631: _HardwareModel.ValueType # 9 - """ - TODO: REPLACE - """ - HELTEC_V2_1: _HardwareModel.ValueType # 10 - """ - The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. - Sadly they did not update anything on the silkscreen to identify this board - """ - HELTEC_V1: _HardwareModel.ValueType # 11 - """ - Ancient heltec WiFi_Lora_32 board - """ - LILYGO_TBEAM_S3_CORE: _HardwareModel.ValueType # 12 - """ - New T-BEAM with ESP32-S3 CPU - """ - RAK11200: _HardwareModel.ValueType # 13 - """ - RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ - """ - NANO_G1: _HardwareModel.ValueType # 14 - """ - B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano - """ - TLORA_V2_1_1P8: _HardwareModel.ValueType # 15 - """ - TODO: REPLACE - """ - TLORA_T3_S3: _HardwareModel.ValueType # 16 - """ - TODO: REPLACE - """ - NANO_G1_EXPLORER: _HardwareModel.ValueType # 17 - """ - B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer - """ - NANO_G2_ULTRA: _HardwareModel.ValueType # 18 - """ - B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra - """ - LORA_TYPE: _HardwareModel.ValueType # 19 - """ - LoRAType device: https://loratype.org/ - """ - WIPHONE: _HardwareModel.ValueType # 20 - """ - wiphone https://www.wiphone.io/ - """ - WIO_WM1110: _HardwareModel.ValueType # 21 - """ - WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk - """ - STATION_G1: _HardwareModel.ValueType # 25 - """ - B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station - """ - RAK11310: _HardwareModel.ValueType # 26 - """ - RAK11310 (RP2040 + SX1262) - """ - SENSELORA_RP2040: _HardwareModel.ValueType # 27 - """ - Makerfabs SenseLoRA Receiver (RP2040 + RFM96) - """ - SENSELORA_S3: _HardwareModel.ValueType # 28 - """ - Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) - """ - CANARYONE: _HardwareModel.ValueType # 29 - """ - Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone - """ - RP2040_LORA: _HardwareModel.ValueType # 30 - """ - Waveshare RP2040 LoRa - https://www.waveshare.com/rp2040-lora.htm - """ - STATION_G2: _HardwareModel.ValueType # 31 - """ - B&Q Consulting Station G2: https://wiki.uniteng.com/en/meshtastic/station-g2 - """ - LORA_RELAY_V1: _HardwareModel.ValueType # 32 - """ - --------------------------------------------------------------------------- - Less common/prototype boards listed here (needs one more byte over the air) - --------------------------------------------------------------------------- - """ - NRF52840DK: _HardwareModel.ValueType # 33 - """ - TODO: REPLACE - """ - PPR: _HardwareModel.ValueType # 34 - """ - TODO: REPLACE - """ - GENIEBLOCKS: _HardwareModel.ValueType # 35 - """ - TODO: REPLACE - """ - NRF52_UNKNOWN: _HardwareModel.ValueType # 36 - """ - TODO: REPLACE - """ - PORTDUINO: _HardwareModel.ValueType # 37 - """ - TODO: REPLACE - """ - ANDROID_SIM: _HardwareModel.ValueType # 38 - """ - The simulator built into the android app - """ - DIY_V1: _HardwareModel.ValueType # 39 - """ - Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics - """ - NRF52840_PCA10059: _HardwareModel.ValueType # 40 - """ - nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ - """ - DR_DEV: _HardwareModel.ValueType # 41 - """ - Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 - """ - M5STACK: _HardwareModel.ValueType # 42 - """ - M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ - """ - HELTEC_V3: _HardwareModel.ValueType # 43 - """ - New Heltec LoRA32 with ESP32-S3 CPU - """ - HELTEC_WSL_V3: _HardwareModel.ValueType # 44 - """ - New Heltec Wireless Stick Lite with ESP32-S3 CPU - """ - BETAFPV_2400_TX: _HardwareModel.ValueType # 45 - """ - New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU - """ - BETAFPV_900_NANO_TX: _HardwareModel.ValueType # 46 - """ - BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU - """ - RPI_PICO: _HardwareModel.ValueType # 47 - """ - Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module - """ - HELTEC_WIRELESS_TRACKER: _HardwareModel.ValueType # 48 - """ - Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT - Newer V1.1, version is written on the PCB near the display. - """ - HELTEC_WIRELESS_PAPER: _HardwareModel.ValueType # 49 - """ - Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display - """ - T_DECK: _HardwareModel.ValueType # 50 - """ - LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display - """ - T_WATCH_S3: _HardwareModel.ValueType # 51 - """ - LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display - """ - PICOMPUTER_S3: _HardwareModel.ValueType # 52 - """ - Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display - """ - HELTEC_HT62: _HardwareModel.ValueType # 53 - """ - Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa - """ - EBYTE_ESP32_S3: _HardwareModel.ValueType # 54 - """ - EBYTE SPI LoRa module and ESP32-S3 - """ - ESP32_S3_PICO: _HardwareModel.ValueType # 55 - """ - Waveshare ESP32-S3-PICO with PICO LoRa HAT and 2.9inch e-Ink - """ - CHATTER_2: _HardwareModel.ValueType # 56 - """ - CircuitMess Chatter 2 LLCC68 Lora Module and ESP32 Wroom - Lora module can be swapped out for a Heltec RA-62 which is "almost" pin compatible - with one cut and one jumper Meshtastic works - """ - HELTEC_WIRELESS_PAPER_V1_0: _HardwareModel.ValueType # 57 - """ - Heltec Wireless Paper, With ESP32-S3 CPU and E-Ink display - Older "V1.0" Variant, has no "version sticker" - E-Ink model is DEPG0213BNS800 - Tab on the screen protector is RED - Flex connector marking is FPC-7528B - """ - HELTEC_WIRELESS_TRACKER_V1_0: _HardwareModel.ValueType # 58 - """ - Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT - Older "V1.0" Variant - """ - UNPHONE: _HardwareModel.ValueType # 59 - """ - unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope - """ - TD_LORAC: _HardwareModel.ValueType # 60 - """ - Teledatics TD-LORAC NRF52840 based M.2 LoRA module - Compatible with the TD-WRLS development board - """ - CDEBYTE_EORA_S3: _HardwareModel.ValueType # 61 - """ - CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 - """ - TWC_MESH_V4: _HardwareModel.ValueType # 62 - """ - TWC_MESH_V4 - Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS - """ - NRF52_PROMICRO_DIY: _HardwareModel.ValueType # 63 - """ - NRF52_PROMICRO_DIY - Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS - """ - RADIOMASTER_900_BANDIT_NANO: _HardwareModel.ValueType # 64 - """ - RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module - ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS - """ - PRIVATE_HW: _HardwareModel.ValueType # 255 - """ - ------------------------------------------------------------------------------------------------------------------------------------------ - Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. - ------------------------------------------------------------------------------------------------------------------------------------------ - """ - -class HardwareModel(_HardwareModel, metaclass=_HardwareModelEnumTypeWrapper): - """ - Note: these enum names must EXACTLY match the string used in the device - bin/build-all.sh script. - Because they will be used to find firmware filenames in the android app for OTA updates. - To match the old style filenames, _ is converted to -, p is converted to . - """ - -UNSET: HardwareModel.ValueType # 0 -""" -TODO: REPLACE -""" -TLORA_V2: HardwareModel.ValueType # 1 -""" -TODO: REPLACE -""" -TLORA_V1: HardwareModel.ValueType # 2 -""" -TODO: REPLACE -""" -TLORA_V2_1_1P6: HardwareModel.ValueType # 3 -""" -TODO: REPLACE -""" -TBEAM: HardwareModel.ValueType # 4 -""" -TODO: REPLACE -""" -HELTEC_V2_0: HardwareModel.ValueType # 5 -""" -The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 -(see HELTEC_V2 for the new version). -""" -TBEAM_V0P7: HardwareModel.ValueType # 6 -""" -TODO: REPLACE -""" -T_ECHO: HardwareModel.ValueType # 7 -""" -TODO: REPLACE -""" -TLORA_V1_1P3: HardwareModel.ValueType # 8 -""" -TODO: REPLACE -""" -RAK4631: HardwareModel.ValueType # 9 -""" -TODO: REPLACE -""" -HELTEC_V2_1: HardwareModel.ValueType # 10 -""" -The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. -Sadly they did not update anything on the silkscreen to identify this board -""" -HELTEC_V1: HardwareModel.ValueType # 11 -""" -Ancient heltec WiFi_Lora_32 board -""" -LILYGO_TBEAM_S3_CORE: HardwareModel.ValueType # 12 -""" -New T-BEAM with ESP32-S3 CPU -""" -RAK11200: HardwareModel.ValueType # 13 -""" -RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ -""" -NANO_G1: HardwareModel.ValueType # 14 -""" -B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano -""" -TLORA_V2_1_1P8: HardwareModel.ValueType # 15 -""" -TODO: REPLACE -""" -TLORA_T3_S3: HardwareModel.ValueType # 16 -""" -TODO: REPLACE -""" -NANO_G1_EXPLORER: HardwareModel.ValueType # 17 -""" -B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer -""" -NANO_G2_ULTRA: HardwareModel.ValueType # 18 -""" -B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra -""" -LORA_TYPE: HardwareModel.ValueType # 19 -""" -LoRAType device: https://loratype.org/ -""" -WIPHONE: HardwareModel.ValueType # 20 -""" -wiphone https://www.wiphone.io/ -""" -WIO_WM1110: HardwareModel.ValueType # 21 -""" -WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk -""" -STATION_G1: HardwareModel.ValueType # 25 -""" -B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station -""" -RAK11310: HardwareModel.ValueType # 26 -""" -RAK11310 (RP2040 + SX1262) -""" -SENSELORA_RP2040: HardwareModel.ValueType # 27 -""" -Makerfabs SenseLoRA Receiver (RP2040 + RFM96) -""" -SENSELORA_S3: HardwareModel.ValueType # 28 -""" -Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) -""" -CANARYONE: HardwareModel.ValueType # 29 -""" -Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone -""" -RP2040_LORA: HardwareModel.ValueType # 30 -""" -Waveshare RP2040 LoRa - https://www.waveshare.com/rp2040-lora.htm -""" -STATION_G2: HardwareModel.ValueType # 31 -""" -B&Q Consulting Station G2: https://wiki.uniteng.com/en/meshtastic/station-g2 -""" -LORA_RELAY_V1: HardwareModel.ValueType # 32 -""" ---------------------------------------------------------------------------- -Less common/prototype boards listed here (needs one more byte over the air) ---------------------------------------------------------------------------- -""" -NRF52840DK: HardwareModel.ValueType # 33 -""" -TODO: REPLACE -""" -PPR: HardwareModel.ValueType # 34 -""" -TODO: REPLACE -""" -GENIEBLOCKS: HardwareModel.ValueType # 35 -""" -TODO: REPLACE -""" -NRF52_UNKNOWN: HardwareModel.ValueType # 36 -""" -TODO: REPLACE -""" -PORTDUINO: HardwareModel.ValueType # 37 -""" -TODO: REPLACE -""" -ANDROID_SIM: HardwareModel.ValueType # 38 -""" -The simulator built into the android app -""" -DIY_V1: HardwareModel.ValueType # 39 -""" -Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics -""" -NRF52840_PCA10059: HardwareModel.ValueType # 40 -""" -nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ -""" -DR_DEV: HardwareModel.ValueType # 41 -""" -Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 -""" -M5STACK: HardwareModel.ValueType # 42 -""" -M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ -""" -HELTEC_V3: HardwareModel.ValueType # 43 -""" -New Heltec LoRA32 with ESP32-S3 CPU -""" -HELTEC_WSL_V3: HardwareModel.ValueType # 44 -""" -New Heltec Wireless Stick Lite with ESP32-S3 CPU -""" -BETAFPV_2400_TX: HardwareModel.ValueType # 45 -""" -New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU -""" -BETAFPV_900_NANO_TX: HardwareModel.ValueType # 46 -""" -BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU -""" -RPI_PICO: HardwareModel.ValueType # 47 -""" -Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module -""" -HELTEC_WIRELESS_TRACKER: HardwareModel.ValueType # 48 -""" -Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT -Newer V1.1, version is written on the PCB near the display. -""" -HELTEC_WIRELESS_PAPER: HardwareModel.ValueType # 49 -""" -Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display -""" -T_DECK: HardwareModel.ValueType # 50 -""" -LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display -""" -T_WATCH_S3: HardwareModel.ValueType # 51 -""" -LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display -""" -PICOMPUTER_S3: HardwareModel.ValueType # 52 -""" -Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display -""" -HELTEC_HT62: HardwareModel.ValueType # 53 -""" -Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa -""" -EBYTE_ESP32_S3: HardwareModel.ValueType # 54 -""" -EBYTE SPI LoRa module and ESP32-S3 -""" -ESP32_S3_PICO: HardwareModel.ValueType # 55 -""" -Waveshare ESP32-S3-PICO with PICO LoRa HAT and 2.9inch e-Ink -""" -CHATTER_2: HardwareModel.ValueType # 56 -""" -CircuitMess Chatter 2 LLCC68 Lora Module and ESP32 Wroom -Lora module can be swapped out for a Heltec RA-62 which is "almost" pin compatible -with one cut and one jumper Meshtastic works -""" -HELTEC_WIRELESS_PAPER_V1_0: HardwareModel.ValueType # 57 -""" -Heltec Wireless Paper, With ESP32-S3 CPU and E-Ink display -Older "V1.0" Variant, has no "version sticker" -E-Ink model is DEPG0213BNS800 -Tab on the screen protector is RED -Flex connector marking is FPC-7528B -""" -HELTEC_WIRELESS_TRACKER_V1_0: HardwareModel.ValueType # 58 -""" -Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT -Older "V1.0" Variant -""" -UNPHONE: HardwareModel.ValueType # 59 -""" -unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope -""" -TD_LORAC: HardwareModel.ValueType # 60 -""" -Teledatics TD-LORAC NRF52840 based M.2 LoRA module -Compatible with the TD-WRLS development board -""" -CDEBYTE_EORA_S3: HardwareModel.ValueType # 61 -""" -CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 -""" -TWC_MESH_V4: HardwareModel.ValueType # 62 -""" -TWC_MESH_V4 -Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS -""" -NRF52_PROMICRO_DIY: HardwareModel.ValueType # 63 -""" -NRF52_PROMICRO_DIY -Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS -""" -RADIOMASTER_900_BANDIT_NANO: HardwareModel.ValueType # 64 -""" -RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module -ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS -""" -PRIVATE_HW: HardwareModel.ValueType # 255 -""" ------------------------------------------------------------------------------------------------------------------------------------------- -Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------- -""" -global___HardwareModel = HardwareModel - -class _Constants: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _ConstantsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Constants.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - ZERO: _Constants.ValueType # 0 - """ - First enum must be zero, and we are just using this enum to - pass int constants between two very different environments - """ - DATA_PAYLOAD_LEN: _Constants.ValueType # 237 - """ - From mesh.options - note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is - outside of this envelope - """ - -class Constants(_Constants, metaclass=_ConstantsEnumTypeWrapper): - """ - Shared constants between device and phone - """ - -ZERO: Constants.ValueType # 0 -""" -First enum must be zero, and we are just using this enum to -pass int constants between two very different environments -""" -DATA_PAYLOAD_LEN: Constants.ValueType # 237 -""" -From mesh.options -note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is -outside of this envelope -""" -global___Constants = Constants - -class _CriticalErrorCode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _CriticalErrorCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CriticalErrorCode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - NONE: _CriticalErrorCode.ValueType # 0 - """ - TODO: REPLACE - """ - TX_WATCHDOG: _CriticalErrorCode.ValueType # 1 - """ - A software bug was detected while trying to send lora - """ - SLEEP_ENTER_WAIT: _CriticalErrorCode.ValueType # 2 - """ - A software bug was detected on entry to sleep - """ - NO_RADIO: _CriticalErrorCode.ValueType # 3 - """ - No Lora radio hardware could be found - """ - UNSPECIFIED: _CriticalErrorCode.ValueType # 4 - """ - Not normally used - """ - UBLOX_UNIT_FAILED: _CriticalErrorCode.ValueType # 5 - """ - We failed while configuring a UBlox GPS - """ - NO_AXP192: _CriticalErrorCode.ValueType # 6 - """ - This board was expected to have a power management chip and it is missing or broken - """ - INVALID_RADIO_SETTING: _CriticalErrorCode.ValueType # 7 - """ - The channel tried to set a radio setting which is not supported by this chipset, - radio comms settings are now undefined. - """ - TRANSMIT_FAILED: _CriticalErrorCode.ValueType # 8 - """ - Radio transmit hardware failure. We sent data to the radio chip, but it didn't - reply with an interrupt. - """ - BROWNOUT: _CriticalErrorCode.ValueType # 9 - """ - We detected that the main CPU voltage dropped below the minimum acceptable value - """ - SX1262_FAILURE: _CriticalErrorCode.ValueType # 10 - """Selftest of SX1262 radio chip failed""" - RADIO_SPI_BUG: _CriticalErrorCode.ValueType # 11 - """ - A (likely software but possibly hardware) failure was detected while trying to send packets. - If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug - """ - -class CriticalErrorCode(_CriticalErrorCode, metaclass=_CriticalErrorCodeEnumTypeWrapper): - """ - Error codes for critical errors - The device might report these fault codes on the screen. - If you encounter a fault code, please post on the meshtastic.discourse.group - and we'll try to help. - """ - -NONE: CriticalErrorCode.ValueType # 0 -""" -TODO: REPLACE -""" -TX_WATCHDOG: CriticalErrorCode.ValueType # 1 -""" -A software bug was detected while trying to send lora -""" -SLEEP_ENTER_WAIT: CriticalErrorCode.ValueType # 2 -""" -A software bug was detected on entry to sleep -""" -NO_RADIO: CriticalErrorCode.ValueType # 3 -""" -No Lora radio hardware could be found -""" -UNSPECIFIED: CriticalErrorCode.ValueType # 4 -""" -Not normally used -""" -UBLOX_UNIT_FAILED: CriticalErrorCode.ValueType # 5 -""" -We failed while configuring a UBlox GPS -""" -NO_AXP192: CriticalErrorCode.ValueType # 6 -""" -This board was expected to have a power management chip and it is missing or broken -""" -INVALID_RADIO_SETTING: CriticalErrorCode.ValueType # 7 -""" -The channel tried to set a radio setting which is not supported by this chipset, -radio comms settings are now undefined. -""" -TRANSMIT_FAILED: CriticalErrorCode.ValueType # 8 -""" -Radio transmit hardware failure. We sent data to the radio chip, but it didn't -reply with an interrupt. -""" -BROWNOUT: CriticalErrorCode.ValueType # 9 -""" -We detected that the main CPU voltage dropped below the minimum acceptable value -""" -SX1262_FAILURE: CriticalErrorCode.ValueType # 10 -"""Selftest of SX1262 radio chip failed""" -RADIO_SPI_BUG: CriticalErrorCode.ValueType # 11 -""" -A (likely software but possibly hardware) failure was detected while trying to send packets. -If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug -""" -global___CriticalErrorCode = CriticalErrorCode - -@typing_extensions.final -class Position(google.protobuf.message.Message): - """ - a gps position - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _LocSource: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _LocSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Position._LocSource.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - LOC_UNSET: Position._LocSource.ValueType # 0 - """ - TODO: REPLACE - """ - LOC_MANUAL: Position._LocSource.ValueType # 1 - """ - TODO: REPLACE - """ - LOC_INTERNAL: Position._LocSource.ValueType # 2 - """ - TODO: REPLACE - """ - LOC_EXTERNAL: Position._LocSource.ValueType # 3 - """ - TODO: REPLACE - """ - - class LocSource(_LocSource, metaclass=_LocSourceEnumTypeWrapper): - """ - How the location was acquired: manual, onboard GPS, external (EUD) GPS - """ - - LOC_UNSET: Position.LocSource.ValueType # 0 - """ - TODO: REPLACE - """ - LOC_MANUAL: Position.LocSource.ValueType # 1 - """ - TODO: REPLACE - """ - LOC_INTERNAL: Position.LocSource.ValueType # 2 - """ - TODO: REPLACE - """ - LOC_EXTERNAL: Position.LocSource.ValueType # 3 - """ - TODO: REPLACE - """ - - class _AltSource: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _AltSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Position._AltSource.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - ALT_UNSET: Position._AltSource.ValueType # 0 - """ - TODO: REPLACE - """ - ALT_MANUAL: Position._AltSource.ValueType # 1 - """ - TODO: REPLACE - """ - ALT_INTERNAL: Position._AltSource.ValueType # 2 - """ - TODO: REPLACE - """ - ALT_EXTERNAL: Position._AltSource.ValueType # 3 - """ - TODO: REPLACE - """ - ALT_BAROMETRIC: Position._AltSource.ValueType # 4 - """ - TODO: REPLACE - """ - - class AltSource(_AltSource, metaclass=_AltSourceEnumTypeWrapper): - """ - How the altitude was acquired: manual, GPS int/ext, etc - Default: same as location_source if present - """ - - ALT_UNSET: Position.AltSource.ValueType # 0 - """ - TODO: REPLACE - """ - ALT_MANUAL: Position.AltSource.ValueType # 1 - """ - TODO: REPLACE - """ - ALT_INTERNAL: Position.AltSource.ValueType # 2 - """ - TODO: REPLACE - """ - ALT_EXTERNAL: Position.AltSource.ValueType # 3 - """ - TODO: REPLACE - """ - ALT_BAROMETRIC: Position.AltSource.ValueType # 4 - """ - TODO: REPLACE - """ - - LATITUDE_I_FIELD_NUMBER: builtins.int - LONGITUDE_I_FIELD_NUMBER: builtins.int - ALTITUDE_FIELD_NUMBER: builtins.int - TIME_FIELD_NUMBER: builtins.int - LOCATION_SOURCE_FIELD_NUMBER: builtins.int - ALTITUDE_SOURCE_FIELD_NUMBER: builtins.int - TIMESTAMP_FIELD_NUMBER: builtins.int - TIMESTAMP_MILLIS_ADJUST_FIELD_NUMBER: builtins.int - ALTITUDE_HAE_FIELD_NUMBER: builtins.int - ALTITUDE_GEOIDAL_SEPARATION_FIELD_NUMBER: builtins.int - PDOP_FIELD_NUMBER: builtins.int - HDOP_FIELD_NUMBER: builtins.int - VDOP_FIELD_NUMBER: builtins.int - GPS_ACCURACY_FIELD_NUMBER: builtins.int - GROUND_SPEED_FIELD_NUMBER: builtins.int - GROUND_TRACK_FIELD_NUMBER: builtins.int - FIX_QUALITY_FIELD_NUMBER: builtins.int - FIX_TYPE_FIELD_NUMBER: builtins.int - SATS_IN_VIEW_FIELD_NUMBER: builtins.int - SENSOR_ID_FIELD_NUMBER: builtins.int - NEXT_UPDATE_FIELD_NUMBER: builtins.int - SEQ_NUMBER_FIELD_NUMBER: builtins.int - PRECISION_BITS_FIELD_NUMBER: builtins.int - latitude_i: builtins.int - """ - The new preferred location encoding, multiply by 1e-7 to get degrees - in floating point - """ - longitude_i: builtins.int - """ - TODO: REPLACE - """ - altitude: builtins.int - """ - In meters above MSL (but see issue #359) - """ - time: builtins.int - """ - This is usually not sent over the mesh (to save space), but it is sent - from the phone so that the local device can set its time if it is sent over - the mesh (because there are devices on the mesh without GPS or RTC). - seconds since 1970 - """ - location_source: global___Position.LocSource.ValueType - """ - TODO: REPLACE - """ - altitude_source: global___Position.AltSource.ValueType - """ - TODO: REPLACE - """ - timestamp: builtins.int - """ - Positional timestamp (actual timestamp of GPS solution) in integer epoch seconds - """ - timestamp_millis_adjust: builtins.int - """ - Pos. timestamp milliseconds adjustment (rarely available or required) - """ - altitude_hae: builtins.int - """ - HAE altitude in meters - can be used instead of MSL altitude - """ - altitude_geoidal_separation: builtins.int - """ - Geoidal separation in meters - """ - PDOP: builtins.int - """ - Horizontal, Vertical and Position Dilution of Precision, in 1/100 units - - PDOP is sufficient for most cases - - for higher precision scenarios, HDOP and VDOP can be used instead, - in which case PDOP becomes redundant (PDOP=sqrt(HDOP^2 + VDOP^2)) - TODO: REMOVE/INTEGRATE - """ - HDOP: builtins.int - """ - TODO: REPLACE - """ - VDOP: builtins.int - """ - TODO: REPLACE - """ - gps_accuracy: builtins.int - """ - GPS accuracy (a hardware specific constant) in mm - multiplied with DOP to calculate positional accuracy - Default: "'bout three meters-ish" :) - """ - ground_speed: builtins.int - """ - Ground speed in m/s and True North TRACK in 1/100 degrees - Clarification of terms: - - "track" is the direction of motion (measured in horizontal plane) - - "heading" is where the fuselage points (measured in horizontal plane) - - "yaw" indicates a relative rotation about the vertical axis - TODO: REMOVE/INTEGRATE - """ - ground_track: builtins.int - """ - TODO: REPLACE - """ - fix_quality: builtins.int - """ - GPS fix quality (from NMEA GxGGA statement or similar) - """ - fix_type: builtins.int - """ - GPS fix type 2D/3D (from NMEA GxGSA statement) - """ - sats_in_view: builtins.int - """ - GPS "Satellites in View" number - """ - sensor_id: builtins.int - """ - Sensor ID - in case multiple positioning sensors are being used - """ - next_update: builtins.int - """ - Estimated/expected time (in seconds) until next update: - - if we update at fixed intervals of X seconds, use X - - if we update at dynamic intervals (based on relative movement etc), - but "AT LEAST every Y seconds", use Y - """ - seq_number: builtins.int - """ - A sequence number, incremented with each Position message to help - detect lost updates if needed - """ - precision_bits: builtins.int - """ - Indicates the bits of precision set by the sending node - """ - def __init__( - self, - *, - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - altitude: builtins.int = ..., - time: builtins.int = ..., - location_source: global___Position.LocSource.ValueType = ..., - altitude_source: global___Position.AltSource.ValueType = ..., - timestamp: builtins.int = ..., - timestamp_millis_adjust: builtins.int = ..., - altitude_hae: builtins.int = ..., - altitude_geoidal_separation: builtins.int = ..., - PDOP: builtins.int = ..., - HDOP: builtins.int = ..., - VDOP: builtins.int = ..., - gps_accuracy: builtins.int = ..., - ground_speed: builtins.int = ..., - ground_track: builtins.int = ..., - fix_quality: builtins.int = ..., - fix_type: builtins.int = ..., - sats_in_view: builtins.int = ..., - sensor_id: builtins.int = ..., - next_update: builtins.int = ..., - seq_number: builtins.int = ..., - precision_bits: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["HDOP", b"HDOP", "PDOP", b"PDOP", "VDOP", b"VDOP", "altitude", b"altitude", "altitude_geoidal_separation", b"altitude_geoidal_separation", "altitude_hae", b"altitude_hae", "altitude_source", b"altitude_source", "fix_quality", b"fix_quality", "fix_type", b"fix_type", "gps_accuracy", b"gps_accuracy", "ground_speed", b"ground_speed", "ground_track", b"ground_track", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "next_update", b"next_update", "precision_bits", b"precision_bits", "sats_in_view", b"sats_in_view", "sensor_id", b"sensor_id", "seq_number", b"seq_number", "time", b"time", "timestamp", b"timestamp", "timestamp_millis_adjust", b"timestamp_millis_adjust"]) -> None: ... - -global___Position = Position - -@typing_extensions.final -class User(google.protobuf.message.Message): - """ - Broadcast when a newly powered mesh node wants to find a node num it can use - Sent from the phone over bluetooth to set the user id for the owner of this node. - Also sent from nodes to each other when a new node signs on (so all clients can have this info) - The algorithm is as follows: - when a node starts up, it broadcasts their user and the normal flow is for all - other nodes to reply with their User as well (so the new node can build its nodedb) - If a node ever receives a User (not just the first broadcast) message where - the sender node number equals our node number, that indicates a collision has - occurred and the following steps should happen: - If the receiving node (that was already in the mesh)'s macaddr is LOWER than the - new User who just tried to sign in: it gets to keep its nodenum. - We send a broadcast message of OUR User (we use a broadcast so that the other node can - receive our message, considering we have the same id - it also serves to let - observers correct their nodedb) - this case is rare so it should be okay. - If any node receives a User where the macaddr is GTE than their local macaddr, - they have been vetoed and should pick a new random nodenum (filtering against - whatever it knows about the nodedb) and rebroadcast their User. - A few nodenums are reserved and will never be requested: - 0xff - broadcast - 0 through 3 - for future use - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ID_FIELD_NUMBER: builtins.int - LONG_NAME_FIELD_NUMBER: builtins.int - SHORT_NAME_FIELD_NUMBER: builtins.int - MACADDR_FIELD_NUMBER: builtins.int - HW_MODEL_FIELD_NUMBER: builtins.int - IS_LICENSED_FIELD_NUMBER: builtins.int - ROLE_FIELD_NUMBER: builtins.int - id: builtins.str - """ - A globally unique ID string for this user. - In the case of Signal that would mean +16504442323, for the default macaddr derived id it would be !<8 hexidecimal bytes>. - Note: app developers are encouraged to also use the following standard - node IDs "^all" (for broadcast), "^local" (for the locally connected node) - """ - long_name: builtins.str - """ - A full name for this user, i.e. "Kevin Hester" - """ - short_name: builtins.str - """ - A VERY short name, ideally two characters. - Suitable for a tiny OLED screen - """ - macaddr: builtins.bytes - """ - Deprecated in Meshtastic 2.1.x - This is the addr of the radio. - Not populated by the phone, but added by the esp32 when broadcasting - """ - hw_model: global___HardwareModel.ValueType - """ - TBEAM, HELTEC, etc... - Starting in 1.2.11 moved to hw_model enum in the NodeInfo object. - Apps will still need the string here for older builds - (so OTA update can find the right image), but if the enum is available it will be used instead. - """ - is_licensed: builtins.bool - """ - In some regions Ham radio operators have different bandwidth limitations than others. - If this user is a licensed operator, set this flag. - Also, "long_name" should be their licence number. - """ - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType - """ - Indicates that the user's role in the mesh - """ - def __init__( - self, - *, - id: builtins.str = ..., - long_name: builtins.str = ..., - short_name: builtins.str = ..., - macaddr: builtins.bytes = ..., - hw_model: global___HardwareModel.ValueType = ..., - is_licensed: builtins.bool = ..., - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["hw_model", b"hw_model", "id", b"id", "is_licensed", b"is_licensed", "long_name", b"long_name", "macaddr", b"macaddr", "role", b"role", "short_name", b"short_name"]) -> None: ... - -global___User = User - -@typing_extensions.final -class RouteDiscovery(google.protobuf.message.Message): - """ - A message used in our Dynamic Source Routing protocol (RFC 4728 based) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ROUTE_FIELD_NUMBER: builtins.int - @property - def route(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """ - The list of nodenums this packet has visited so far - """ - def __init__( - self, - *, - route: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["route", b"route"]) -> None: ... - -global___RouteDiscovery = RouteDiscovery - -@typing_extensions.final -class Routing(google.protobuf.message.Message): - """ - A Routing control Data packet handled by the routing module - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Error: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Routing._Error.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - NONE: Routing._Error.ValueType # 0 - """ - This message is not a failure - """ - NO_ROUTE: Routing._Error.ValueType # 1 - """ - Our node doesn't have a route to the requested destination anymore. - """ - GOT_NAK: Routing._Error.ValueType # 2 - """ - We received a nak while trying to forward on your behalf - """ - TIMEOUT: Routing._Error.ValueType # 3 - """ - TODO: REPLACE - """ - NO_INTERFACE: Routing._Error.ValueType # 4 - """ - No suitable interface could be found for delivering this packet - """ - MAX_RETRANSMIT: Routing._Error.ValueType # 5 - """ - We reached the max retransmission count (typically for naive flood routing) - """ - NO_CHANNEL: Routing._Error.ValueType # 6 - """ - No suitable channel was found for sending this packet (i.e. was requested channel index disabled?) - """ - TOO_LARGE: Routing._Error.ValueType # 7 - """ - The packet was too big for sending (exceeds interface MTU after encoding) - """ - NO_RESPONSE: Routing._Error.ValueType # 8 - """ - The request had want_response set, the request reached the destination node, but no service on that node wants to send a response - (possibly due to bad channel permissions) - """ - DUTY_CYCLE_LIMIT: Routing._Error.ValueType # 9 - """ - Cannot send currently because duty cycle regulations will be violated. - """ - BAD_REQUEST: Routing._Error.ValueType # 32 - """ - The application layer service on the remote node received your request, but considered your request somehow invalid - """ - NOT_AUTHORIZED: Routing._Error.ValueType # 33 - """ - The application layer service on the remote node received your request, but considered your request not authorized - (i.e you did not send the request on the required bound channel) - """ - - class Error(_Error, metaclass=_ErrorEnumTypeWrapper): - """ - A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide - details on the type of failure). - """ - - NONE: Routing.Error.ValueType # 0 - """ - This message is not a failure - """ - NO_ROUTE: Routing.Error.ValueType # 1 - """ - Our node doesn't have a route to the requested destination anymore. - """ - GOT_NAK: Routing.Error.ValueType # 2 - """ - We received a nak while trying to forward on your behalf - """ - TIMEOUT: Routing.Error.ValueType # 3 - """ - TODO: REPLACE - """ - NO_INTERFACE: Routing.Error.ValueType # 4 - """ - No suitable interface could be found for delivering this packet - """ - MAX_RETRANSMIT: Routing.Error.ValueType # 5 - """ - We reached the max retransmission count (typically for naive flood routing) - """ - NO_CHANNEL: Routing.Error.ValueType # 6 - """ - No suitable channel was found for sending this packet (i.e. was requested channel index disabled?) - """ - TOO_LARGE: Routing.Error.ValueType # 7 - """ - The packet was too big for sending (exceeds interface MTU after encoding) - """ - NO_RESPONSE: Routing.Error.ValueType # 8 - """ - The request had want_response set, the request reached the destination node, but no service on that node wants to send a response - (possibly due to bad channel permissions) - """ - DUTY_CYCLE_LIMIT: Routing.Error.ValueType # 9 - """ - Cannot send currently because duty cycle regulations will be violated. - """ - BAD_REQUEST: Routing.Error.ValueType # 32 - """ - The application layer service on the remote node received your request, but considered your request somehow invalid - """ - NOT_AUTHORIZED: Routing.Error.ValueType # 33 - """ - The application layer service on the remote node received your request, but considered your request not authorized - (i.e you did not send the request on the required bound channel) - """ - - ROUTE_REQUEST_FIELD_NUMBER: builtins.int - ROUTE_REPLY_FIELD_NUMBER: builtins.int - ERROR_REASON_FIELD_NUMBER: builtins.int - @property - def route_request(self) -> global___RouteDiscovery: - """ - A route request going from the requester - """ - @property - def route_reply(self) -> global___RouteDiscovery: - """ - A route reply - """ - error_reason: global___Routing.Error.ValueType - """ - A failure in delivering a message (usually used for routing control messages, but might be provided - in addition to ack.fail_id to provide details on the type of failure). - """ - def __init__( - self, - *, - route_request: global___RouteDiscovery | None = ..., - route_reply: global___RouteDiscovery | None = ..., - error_reason: global___Routing.Error.ValueType = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["error_reason", b"error_reason", "route_reply", b"route_reply", "route_request", b"route_request", "variant", b"variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["error_reason", b"error_reason", "route_reply", b"route_reply", "route_request", b"route_request", "variant", b"variant"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["variant", b"variant"]) -> typing_extensions.Literal["route_request", "route_reply", "error_reason"] | None: ... - -global___Routing = Routing - -@typing_extensions.final -class Data(google.protobuf.message.Message): - """ - (Formerly called SubPacket) - The payload portion fo a packet, this is the actual bytes that are sent - inside a radio packet (because from/to are broken out by the comms library) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PORTNUM_FIELD_NUMBER: builtins.int - PAYLOAD_FIELD_NUMBER: builtins.int - WANT_RESPONSE_FIELD_NUMBER: builtins.int - DEST_FIELD_NUMBER: builtins.int - SOURCE_FIELD_NUMBER: builtins.int - REQUEST_ID_FIELD_NUMBER: builtins.int - REPLY_ID_FIELD_NUMBER: builtins.int - EMOJI_FIELD_NUMBER: builtins.int - portnum: meshtastic.portnums_pb2.PortNum.ValueType - """ - Formerly named typ and of type Type - """ - payload: builtins.bytes - """ - TODO: REPLACE - """ - want_response: builtins.bool - """ - Not normally used, but for testing a sender can request that recipient - responds in kind (i.e. if it received a position, it should unicast back it's position). - Note: that if you set this on a broadcast you will receive many replies. - """ - dest: builtins.int - """ - The address of the destination node. - This field is is filled in by the mesh radio device software, application - layer software should never need it. - RouteDiscovery messages _must_ populate this. - Other message types might need to if they are doing multihop routing. - """ - source: builtins.int - """ - The address of the original sender for this message. - This field should _only_ be populated for reliable multihop packets (to keep - packets small). - """ - request_id: builtins.int - """ - Only used in routing or response messages. - Indicates the original message ID that this message is reporting failure on. (formerly called original_id) - """ - reply_id: builtins.int - """ - If set, this message is intened to be a reply to a previously sent message with the defined id. - """ - emoji: builtins.int - """ - Defaults to false. If true, then what is in the payload should be treated as an emoji like giving - a message a heart or poop emoji. - """ - def __init__( - self, - *, - portnum: meshtastic.portnums_pb2.PortNum.ValueType = ..., - payload: builtins.bytes = ..., - want_response: builtins.bool = ..., - dest: builtins.int = ..., - source: builtins.int = ..., - request_id: builtins.int = ..., - reply_id: builtins.int = ..., - emoji: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["dest", b"dest", "emoji", b"emoji", "payload", b"payload", "portnum", b"portnum", "reply_id", b"reply_id", "request_id", b"request_id", "source", b"source", "want_response", b"want_response"]) -> None: ... - -global___Data = Data - -@typing_extensions.final -class Waypoint(google.protobuf.message.Message): - """ - Waypoint message, used to share arbitrary locations across the mesh - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ID_FIELD_NUMBER: builtins.int - LATITUDE_I_FIELD_NUMBER: builtins.int - LONGITUDE_I_FIELD_NUMBER: builtins.int - EXPIRE_FIELD_NUMBER: builtins.int - LOCKED_TO_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - DESCRIPTION_FIELD_NUMBER: builtins.int - ICON_FIELD_NUMBER: builtins.int - id: builtins.int - """ - Id of the waypoint - """ - latitude_i: builtins.int - """ - latitude_i - """ - longitude_i: builtins.int - """ - longitude_i - """ - expire: builtins.int - """ - Time the waypoint is to expire (epoch) - """ - locked_to: builtins.int - """ - If greater than zero, treat the value as a nodenum only allowing them to update the waypoint. - If zero, the waypoint is open to be edited by any member of the mesh. - """ - name: builtins.str - """ - Name of the waypoint - max 30 chars - """ - description: builtins.str - """ - Description of the waypoint - max 100 chars - """ - icon: builtins.int - """ - Designator icon for the waypoint in the form of a unicode emoji - """ - def __init__( - self, - *, - id: builtins.int = ..., - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - expire: builtins.int = ..., - locked_to: builtins.int = ..., - name: builtins.str = ..., - description: builtins.str = ..., - icon: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "expire", b"expire", "icon", b"icon", "id", b"id", "latitude_i", b"latitude_i", "locked_to", b"locked_to", "longitude_i", b"longitude_i", "name", b"name"]) -> None: ... - -global___Waypoint = Waypoint - -@typing_extensions.final -class MqttClientProxyMessage(google.protobuf.message.Message): - """ - This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TOPIC_FIELD_NUMBER: builtins.int - DATA_FIELD_NUMBER: builtins.int - TEXT_FIELD_NUMBER: builtins.int - RETAINED_FIELD_NUMBER: builtins.int - topic: builtins.str - """ - The MQTT topic this message will be sent /received on - """ - data: builtins.bytes - """ - Bytes - """ - text: builtins.str - """ - Text - """ - retained: builtins.bool - """ - Whether the message should be retained (or not) - """ - def __init__( - self, - *, - topic: builtins.str = ..., - data: builtins.bytes = ..., - text: builtins.str = ..., - retained: builtins.bool = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["data", b"data", "payload_variant", b"payload_variant", "text", b"text"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["data", b"data", "payload_variant", b"payload_variant", "retained", b"retained", "text", b"text", "topic", b"topic"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["data", "text"] | None: ... - -global___MqttClientProxyMessage = MqttClientProxyMessage - -@typing_extensions.final -class MeshPacket(google.protobuf.message.Message): - """ - A packet envelope sent/received over the mesh - only payload_variant is sent in the payload portion of the LORA packet. - The other fields are either not sent at all, or sent in the special 16 byte LORA header. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Priority: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _PriorityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MeshPacket._Priority.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: MeshPacket._Priority.ValueType # 0 - """ - Treated as Priority.DEFAULT - """ - MIN: MeshPacket._Priority.ValueType # 1 - """ - TODO: REPLACE - """ - BACKGROUND: MeshPacket._Priority.ValueType # 10 - """ - Background position updates are sent with very low priority - - if the link is super congested they might not go out at all - """ - DEFAULT: MeshPacket._Priority.ValueType # 64 - """ - This priority is used for most messages that don't have a priority set - """ - RELIABLE: MeshPacket._Priority.ValueType # 70 - """ - If priority is unset but the message is marked as want_ack, - assume it is important and use a slightly higher priority - """ - ACK: MeshPacket._Priority.ValueType # 120 - """ - Ack/naks are sent with very high priority to ensure that retransmission - stops as soon as possible - """ - MAX: MeshPacket._Priority.ValueType # 127 - """ - TODO: REPLACE - """ - - class Priority(_Priority, metaclass=_PriorityEnumTypeWrapper): - """ - The priority of this message for sending. - Higher priorities are sent first (when managing the transmit queue). - This field is never sent over the air, it is only used internally inside of a local device node. - API clients (either on the local node or connected directly to the node) - can set this parameter if necessary. - (values must be <= 127 to keep protobuf field to one byte in size. - Detailed background on this field: - I noticed a funny side effect of lora being so slow: Usually when making - a protocol there isn’t much need to use message priority to change the order - of transmission (because interfaces are fairly fast). - But for lora where packets can take a few seconds each, it is very important - to make sure that critical packets are sent ASAP. - In the case of meshtastic that means we want to send protocol acks as soon as possible - (to prevent unneeded retransmissions), we want routing messages to be sent next, - then messages marked as reliable and finally 'background' packets like periodic position updates. - So I bit the bullet and implemented a new (internal - not sent over the air) - field in MeshPacket called 'priority'. - And the transmission queue in the router object is now a priority queue. - """ - - UNSET: MeshPacket.Priority.ValueType # 0 - """ - Treated as Priority.DEFAULT - """ - MIN: MeshPacket.Priority.ValueType # 1 - """ - TODO: REPLACE - """ - BACKGROUND: MeshPacket.Priority.ValueType # 10 - """ - Background position updates are sent with very low priority - - if the link is super congested they might not go out at all - """ - DEFAULT: MeshPacket.Priority.ValueType # 64 - """ - This priority is used for most messages that don't have a priority set - """ - RELIABLE: MeshPacket.Priority.ValueType # 70 - """ - If priority is unset but the message is marked as want_ack, - assume it is important and use a slightly higher priority - """ - ACK: MeshPacket.Priority.ValueType # 120 - """ - Ack/naks are sent with very high priority to ensure that retransmission - stops as soon as possible - """ - MAX: MeshPacket.Priority.ValueType # 127 - """ - TODO: REPLACE - """ - - class _Delayed: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _DelayedEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MeshPacket._Delayed.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - NO_DELAY: MeshPacket._Delayed.ValueType # 0 - """ - If unset, the message is being sent in real time. - """ - DELAYED_BROADCAST: MeshPacket._Delayed.ValueType # 1 - """ - The message is delayed and was originally a broadcast - """ - DELAYED_DIRECT: MeshPacket._Delayed.ValueType # 2 - """ - The message is delayed and was originally a direct message - """ - - class Delayed(_Delayed, metaclass=_DelayedEnumTypeWrapper): - """ - Identify if this is a delayed packet - """ - - NO_DELAY: MeshPacket.Delayed.ValueType # 0 - """ - If unset, the message is being sent in real time. - """ - DELAYED_BROADCAST: MeshPacket.Delayed.ValueType # 1 - """ - The message is delayed and was originally a broadcast - """ - DELAYED_DIRECT: MeshPacket.Delayed.ValueType # 2 - """ - The message is delayed and was originally a direct message - """ - - FROM_FIELD_NUMBER: builtins.int - TO_FIELD_NUMBER: builtins.int - CHANNEL_FIELD_NUMBER: builtins.int - DECODED_FIELD_NUMBER: builtins.int - ENCRYPTED_FIELD_NUMBER: builtins.int - ID_FIELD_NUMBER: builtins.int - RX_TIME_FIELD_NUMBER: builtins.int - RX_SNR_FIELD_NUMBER: builtins.int - HOP_LIMIT_FIELD_NUMBER: builtins.int - WANT_ACK_FIELD_NUMBER: builtins.int - PRIORITY_FIELD_NUMBER: builtins.int - RX_RSSI_FIELD_NUMBER: builtins.int - DELAYED_FIELD_NUMBER: builtins.int - VIA_MQTT_FIELD_NUMBER: builtins.int - HOP_START_FIELD_NUMBER: builtins.int - to: builtins.int - """ - The (immediate) destination for this packet - """ - channel: builtins.int - """ - (Usually) If set, this indicates the index in the secondary_channels table that this packet was sent/received on. - If unset, packet was on the primary channel. - A particular node might know only a subset of channels in use on the mesh. - Therefore channel_index is inherently a local concept and meaningless to send between nodes. - Very briefly, while sending and receiving deep inside the device Router code, this field instead - contains the 'channel hash' instead of the index. - This 'trick' is only used while the payload_variant is an 'encrypted'. - """ - @property - def decoded(self) -> global___Data: - """ - TODO: REPLACE - """ - encrypted: builtins.bytes - """ - TODO: REPLACE - """ - id: builtins.int - """ - A unique ID for this packet. - Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space). - Otherwise a unique ID for this packet, useful for flooding algorithms. - ID only needs to be unique on a _per sender_ basis, and it only - needs to be unique for a few minutes (long enough to last for the length of - any ACK or the completion of a mesh broadcast flood). - Note: Our crypto implementation uses this id as well. - See [crypto](/docs/overview/encryption) for details. - """ - rx_time: builtins.int - """ - The time this message was received by the esp32 (secs since 1970). - Note: this field is _never_ sent on the radio link itself (to save space) Times - are typically not sent over the mesh, but they will be added to any Packet - (chain of SubPacket) sent to the phone (so the phone can know exact time of reception) - """ - rx_snr: builtins.float - """ - *Never* sent over the radio links. - Set during reception to indicate the SNR of this packet. - Used to collect statistics on current link quality. - """ - hop_limit: builtins.int - """ - If unset treated as zero (no forwarding, send to adjacent nodes only) - if 1, allow hopping through one node, etc... - For our usecase real world topologies probably have a max of about 3. - This field is normally placed into a few of bits in the header. - """ - want_ack: builtins.bool - """ - This packet is being sent as a reliable message, we would prefer it to arrive at the destination. - We would like to receive a ack packet in response. - Broadcasts messages treat this flag specially: Since acks for broadcasts would - rapidly flood the channel, the normal ack behavior is suppressed. - Instead, the original sender listens to see if at least one node is rebroadcasting this packet (because naive flooding algorithm). - If it hears that the odds (given typical LoRa topologies) the odds are very high that every node should eventually receive the message. - So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender. - If after some time we don't hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic. - Note: This flag is normally sent in a flag bit in the header when sent over the wire - """ - priority: global___MeshPacket.Priority.ValueType - """ - The priority of this message for sending. - See MeshPacket.Priority description for more details. - """ - rx_rssi: builtins.int - """ - rssi of received packet. Only sent to phone for dispay purposes. - """ - delayed: global___MeshPacket.Delayed.ValueType - """ - Describe if this message is delayed - """ - via_mqtt: builtins.bool - """ - Describes whether this packet passed via MQTT somewhere along the path it currently took. - """ - hop_start: builtins.int - """ - Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header. - When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled. - """ - def __init__( - self, - *, - to: builtins.int = ..., - channel: builtins.int = ..., - decoded: global___Data | None = ..., - encrypted: builtins.bytes = ..., - id: builtins.int = ..., - rx_time: builtins.int = ..., - rx_snr: builtins.float = ..., - hop_limit: builtins.int = ..., - want_ack: builtins.bool = ..., - priority: global___MeshPacket.Priority.ValueType = ..., - rx_rssi: builtins.int = ..., - delayed: global___MeshPacket.Delayed.ValueType = ..., - via_mqtt: builtins.bool = ..., - hop_start: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["decoded", b"decoded", "encrypted", b"encrypted", "payload_variant", b"payload_variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.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", "payload_variant", b"payload_variant", "priority", b"priority", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "via_mqtt", b"via_mqtt", "want_ack", b"want_ack"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["decoded", "encrypted"] | None: ... - -global___MeshPacket = MeshPacket - -@typing_extensions.final -class NodeInfo(google.protobuf.message.Message): - """ - The bluetooth to device link: - Old BTLE protocol docs from TODO, merge in above and make real docs... - use protocol buffers, and NanoPB - messages from device to phone: - POSITION_UPDATE (..., time) - TEXT_RECEIVED(from, text, time) - OPAQUE_RECEIVED(from, payload, time) (for signal messages or other applications) - messages from phone to device: - SET_MYID(id, human readable long, human readable short) (send down the unique ID - string used for this node, a human readable string shown for that id, and a very - short human readable string suitable for oled screen) SEND_OPAQUE(dest, payload) - (for signal messages or other applications) SEND_TEXT(dest, text) Get all - nodes() (returns list of nodes, with full info, last time seen, loc, battery - level etc) SET_CONFIG (switches device to a new set of radio params and - preshared key, drops all existing nodes, force our node to rejoin this new group) - Full information about a node on the mesh - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NUM_FIELD_NUMBER: builtins.int - USER_FIELD_NUMBER: builtins.int - POSITION_FIELD_NUMBER: builtins.int - SNR_FIELD_NUMBER: builtins.int - LAST_HEARD_FIELD_NUMBER: builtins.int - DEVICE_METRICS_FIELD_NUMBER: builtins.int - CHANNEL_FIELD_NUMBER: builtins.int - VIA_MQTT_FIELD_NUMBER: builtins.int - HOPS_AWAY_FIELD_NUMBER: builtins.int - IS_FAVORITE_FIELD_NUMBER: builtins.int - num: builtins.int - """ - The node number - """ - @property - def user(self) -> global___User: - """ - The user info for this node - """ - @property - def position(self) -> global___Position: - """ - This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. - Position.time now indicates the last time we received a POSITION from that node. - """ - snr: builtins.float - """ - Returns the Signal-to-noise ratio (SNR) of the last received message, - as measured by the receiver. Return SNR of the last received message in dB - """ - last_heard: builtins.int - """ - TODO: REMOVE/INTEGRATE - Not currently used (till full DSR deployment?) Our current preferred node node for routing - might be the same as num if - we are adjacent Or zero if we don't yet know a route to this node. - fixed32 next_hop = 5; - - - Set to indicate the last time we received a packet from this node - """ - @property - def device_metrics(self) -> meshtastic.telemetry_pb2.DeviceMetrics: - """ - The latest device metrics for the node. - """ - channel: builtins.int - """ - local channel index we heard that node on. Only populated if its not the default channel. - """ - via_mqtt: builtins.bool - """ - True if we witnessed the node over MQTT instead of LoRA transport - """ - hops_away: builtins.int - """ - Number of hops away from us this node is (0 if adjacent) - """ - is_favorite: builtins.bool - """ - True if node is in our favorites list - Persists between NodeDB internal clean ups - """ - def __init__( - self, - *, - num: builtins.int = ..., - user: global___User | None = ..., - position: global___Position | None = ..., - snr: builtins.float = ..., - last_heard: builtins.int = ..., - device_metrics: meshtastic.telemetry_pb2.DeviceMetrics | None = ..., - channel: builtins.int = ..., - via_mqtt: builtins.bool = ..., - hops_away: builtins.int = ..., - is_favorite: builtins.bool = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ... - -global___NodeInfo = NodeInfo - -@typing_extensions.final -class MyNodeInfo(google.protobuf.message.Message): - """ - Unique local debugging info for this node - Note: we don't include position or the user info, because that will come in the - Sent to the phone in response to WantNodes. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MY_NODE_NUM_FIELD_NUMBER: builtins.int - REBOOT_COUNT_FIELD_NUMBER: builtins.int - MIN_APP_VERSION_FIELD_NUMBER: builtins.int - my_node_num: builtins.int - """ - Tells the phone what our node number is, default starting value is - lowbyte of macaddr, but it will be fixed if that is already in use - """ - reboot_count: builtins.int - """ - The total number of reboots this node has ever encountered - (well - since the last time we discarded preferences) - """ - min_app_version: builtins.int - """ - The minimum app version that can talk to this device. - Phone/PC apps should compare this to their build number and if too low tell the user they must update their app - """ - def __init__( - self, - *, - my_node_num: builtins.int = ..., - reboot_count: builtins.int = ..., - min_app_version: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["min_app_version", b"min_app_version", "my_node_num", b"my_node_num", "reboot_count", b"reboot_count"]) -> None: ... - -global___MyNodeInfo = MyNodeInfo - -@typing_extensions.final -class LogRecord(google.protobuf.message.Message): - """ - Debug output from the device. - To minimize the size of records inside the device code, if a time/source/level is not set - on the message it is assumed to be a continuation of the previously sent message. - This allows the device code to use fixed maxlen 64 byte strings for messages, - and then extend as needed by emitting multiple records. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Level: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _LevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[LogRecord._Level.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: LogRecord._Level.ValueType # 0 - """ - Log levels, chosen to match python logging conventions. - """ - CRITICAL: LogRecord._Level.ValueType # 50 - """ - Log levels, chosen to match python logging conventions. - """ - ERROR: LogRecord._Level.ValueType # 40 - """ - Log levels, chosen to match python logging conventions. - """ - WARNING: LogRecord._Level.ValueType # 30 - """ - Log levels, chosen to match python logging conventions. - """ - INFO: LogRecord._Level.ValueType # 20 - """ - Log levels, chosen to match python logging conventions. - """ - DEBUG: LogRecord._Level.ValueType # 10 - """ - Log levels, chosen to match python logging conventions. - """ - TRACE: LogRecord._Level.ValueType # 5 - """ - Log levels, chosen to match python logging conventions. - """ - - class Level(_Level, metaclass=_LevelEnumTypeWrapper): - """ - Log levels, chosen to match python logging conventions. - """ - - UNSET: LogRecord.Level.ValueType # 0 - """ - Log levels, chosen to match python logging conventions. - """ - CRITICAL: LogRecord.Level.ValueType # 50 - """ - Log levels, chosen to match python logging conventions. - """ - ERROR: LogRecord.Level.ValueType # 40 - """ - Log levels, chosen to match python logging conventions. - """ - WARNING: LogRecord.Level.ValueType # 30 - """ - Log levels, chosen to match python logging conventions. - """ - INFO: LogRecord.Level.ValueType # 20 - """ - Log levels, chosen to match python logging conventions. - """ - DEBUG: LogRecord.Level.ValueType # 10 - """ - Log levels, chosen to match python logging conventions. - """ - TRACE: LogRecord.Level.ValueType # 5 - """ - Log levels, chosen to match python logging conventions. - """ - - MESSAGE_FIELD_NUMBER: builtins.int - TIME_FIELD_NUMBER: builtins.int - SOURCE_FIELD_NUMBER: builtins.int - LEVEL_FIELD_NUMBER: builtins.int - message: builtins.str - """ - Log levels, chosen to match python logging conventions. - """ - time: builtins.int - """ - Seconds since 1970 - or 0 for unknown/unset - """ - source: builtins.str - """ - Usually based on thread name - if known - """ - level: global___LogRecord.Level.ValueType - """ - Not yet set - """ - def __init__( - self, - *, - message: builtins.str = ..., - time: builtins.int = ..., - source: builtins.str = ..., - level: global___LogRecord.Level.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["level", b"level", "message", b"message", "source", b"source", "time", b"time"]) -> None: ... - -global___LogRecord = LogRecord - -@typing_extensions.final -class QueueStatus(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RES_FIELD_NUMBER: builtins.int - FREE_FIELD_NUMBER: builtins.int - MAXLEN_FIELD_NUMBER: builtins.int - MESH_PACKET_ID_FIELD_NUMBER: builtins.int - res: builtins.int - """Last attempt to queue status, ErrorCode""" - free: builtins.int - """Free entries in the outgoing queue""" - maxlen: builtins.int - """Maximum entries in the outgoing queue""" - mesh_packet_id: builtins.int - """What was mesh packet id that generated this response?""" - def __init__( - self, - *, - res: builtins.int = ..., - free: builtins.int = ..., - maxlen: builtins.int = ..., - mesh_packet_id: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["free", b"free", "maxlen", b"maxlen", "mesh_packet_id", b"mesh_packet_id", "res", b"res"]) -> None: ... - -global___QueueStatus = QueueStatus - -@typing_extensions.final -class FromRadio(google.protobuf.message.Message): - """ - Packets from the radio to the phone will appear on the fromRadio characteristic. - It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? - It will sit in that descriptor until consumed by the phone, - at which point the next item in the FIFO will be populated. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ID_FIELD_NUMBER: builtins.int - PACKET_FIELD_NUMBER: builtins.int - MY_INFO_FIELD_NUMBER: builtins.int - NODE_INFO_FIELD_NUMBER: builtins.int - CONFIG_FIELD_NUMBER: builtins.int - LOG_RECORD_FIELD_NUMBER: builtins.int - CONFIG_COMPLETE_ID_FIELD_NUMBER: builtins.int - REBOOTED_FIELD_NUMBER: builtins.int - MODULECONFIG_FIELD_NUMBER: builtins.int - CHANNEL_FIELD_NUMBER: builtins.int - QUEUESTATUS_FIELD_NUMBER: builtins.int - XMODEMPACKET_FIELD_NUMBER: builtins.int - METADATA_FIELD_NUMBER: builtins.int - MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int - id: builtins.int - """ - The packet id, used to allow the phone to request missing read packets from the FIFO, - see our bluetooth docs - """ - @property - def packet(self) -> global___MeshPacket: - """ - Log levels, chosen to match python logging conventions. - """ - @property - def my_info(self) -> global___MyNodeInfo: - """ - Tells the phone what our node number is, can be -1 if we've not yet joined a mesh. - NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. - """ - @property - def node_info(self) -> global___NodeInfo: - """ - One packet is sent for each node in the on radio DB - starts over with the first node in our DB - """ - @property - def config(self) -> meshtastic.config_pb2.Config: - """ - Include a part of the config (was: RadioConfig radio) - """ - @property - def log_record(self) -> global___LogRecord: - """ - Set to send debug console output over our protobuf stream - """ - config_complete_id: builtins.int - """ - Sent as true once the device has finished sending all of the responses to want_config - recipient should check if this ID matches our original request nonce, if - not, it means your config responses haven't started yet. - NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. - """ - rebooted: builtins.bool - """ - Sent to tell clients the radio has just rebooted. - Set to true if present. - Not used on all transports, currently just used for the serial console. - NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. - """ - @property - def moduleConfig(self) -> meshtastic.module_config_pb2.ModuleConfig: - """ - Include module config - """ - @property - def channel(self) -> meshtastic.channel_pb2.Channel: - """ - One packet is sent for each channel - """ - @property - def queueStatus(self) -> global___QueueStatus: - """ - Queue status info - """ - @property - def xmodemPacket(self) -> meshtastic.xmodem_pb2.XModem: - """ - File Transfer Chunk - """ - @property - def metadata(self) -> global___DeviceMetadata: - """ - Device metadata message - """ - @property - def mqttClientProxyMessage(self) -> global___MqttClientProxyMessage: - """ - MQTT Client Proxy Message (device sending to client / phone for publishing to MQTT) - """ - def __init__( - self, - *, - id: builtins.int = ..., - packet: global___MeshPacket | None = ..., - my_info: global___MyNodeInfo | None = ..., - node_info: global___NodeInfo | None = ..., - config: meshtastic.config_pb2.Config | None = ..., - log_record: global___LogRecord | None = ..., - config_complete_id: builtins.int = ..., - rebooted: builtins.bool = ..., - moduleConfig: meshtastic.module_config_pb2.ModuleConfig | None = ..., - channel: meshtastic.channel_pb2.Channel | None = ..., - queueStatus: global___QueueStatus | None = ..., - xmodemPacket: meshtastic.xmodem_pb2.XModem | None = ..., - metadata: global___DeviceMetadata | None = ..., - mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage"] | None: ... - -global___FromRadio = FromRadio - -@typing_extensions.final -class ToRadio(google.protobuf.message.Message): - """ - Packets/commands to the radio will be written (reliably) to the toRadio characteristic. - Once the write completes the phone can assume it is handled. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PACKET_FIELD_NUMBER: builtins.int - WANT_CONFIG_ID_FIELD_NUMBER: builtins.int - DISCONNECT_FIELD_NUMBER: builtins.int - XMODEMPACKET_FIELD_NUMBER: builtins.int - MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int - HEARTBEAT_FIELD_NUMBER: builtins.int - @property - def packet(self) -> global___MeshPacket: - """ - Send this packet on the mesh - """ - want_config_id: builtins.int - """ - Phone wants radio to send full node db to the phone, This is - typically the first packet sent to the radio when the phone gets a - bluetooth connection. The radio will respond by sending back a - MyNodeInfo, a owner, a radio config and a series of - FromRadio.node_infos, and config_complete - the integer you write into this field will be reported back in the - config_complete_id response this allows clients to never be confused by - a stale old partially sent config. - """ - disconnect: builtins.bool - """ - Tell API server we are disconnecting now. - This is useful for serial links where there is no hardware/protocol based notification that the client has dropped the link. - (Sending this message is optional for clients) - """ - @property - def xmodemPacket(self) -> meshtastic.xmodem_pb2.XModem: - """ - File Transfer Chunk - """ - @property - def mqttClientProxyMessage(self) -> global___MqttClientProxyMessage: - """ - MQTT Client Proxy Message (for client / phone subscribed to MQTT sending to device) - """ - @property - def heartbeat(self) -> global___Heartbeat: - """ - Heartbeat message (used to keep the device connection awake on serial) - """ - def __init__( - self, - *, - packet: global___MeshPacket | None = ..., - want_config_id: builtins.int = ..., - disconnect: builtins.bool = ..., - xmodemPacket: meshtastic.xmodem_pb2.XModem | None = ..., - mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., - heartbeat: global___Heartbeat | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["disconnect", b"disconnect", "heartbeat", b"heartbeat", "mqttClientProxyMessage", b"mqttClientProxyMessage", "packet", b"packet", "payload_variant", b"payload_variant", "want_config_id", b"want_config_id", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["disconnect", b"disconnect", "heartbeat", b"heartbeat", "mqttClientProxyMessage", b"mqttClientProxyMessage", "packet", b"packet", "payload_variant", b"payload_variant", "want_config_id", b"want_config_id", "xmodemPacket", b"xmodemPacket"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["packet", "want_config_id", "disconnect", "xmodemPacket", "mqttClientProxyMessage", "heartbeat"] | None: ... - -global___ToRadio = ToRadio - -@typing_extensions.final -class Compressed(google.protobuf.message.Message): - """ - Compressed message payload - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PORTNUM_FIELD_NUMBER: builtins.int - DATA_FIELD_NUMBER: builtins.int - portnum: meshtastic.portnums_pb2.PortNum.ValueType - """ - PortNum to determine the how to handle the compressed payload. - """ - data: builtins.bytes - """ - Compressed data. - """ - def __init__( - self, - *, - portnum: meshtastic.portnums_pb2.PortNum.ValueType = ..., - data: builtins.bytes = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["data", b"data", "portnum", b"portnum"]) -> None: ... - -global___Compressed = Compressed - -@typing_extensions.final -class NeighborInfo(google.protobuf.message.Message): - """ - Full info on edges for a single node - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NODE_ID_FIELD_NUMBER: builtins.int - LAST_SENT_BY_ID_FIELD_NUMBER: builtins.int - NODE_BROADCAST_INTERVAL_SECS_FIELD_NUMBER: builtins.int - NEIGHBORS_FIELD_NUMBER: builtins.int - node_id: builtins.int - """ - The node ID of the node sending info on its neighbors - """ - last_sent_by_id: builtins.int - """ - Field to pass neighbor info for the next sending cycle - """ - node_broadcast_interval_secs: builtins.int - """ - Broadcast interval of the represented node (in seconds) - """ - @property - def neighbors(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Neighbor]: - """ - The list of out edges from this node - """ - def __init__( - self, - *, - node_id: builtins.int = ..., - last_sent_by_id: builtins.int = ..., - node_broadcast_interval_secs: builtins.int = ..., - neighbors: collections.abc.Iterable[global___Neighbor] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["last_sent_by_id", b"last_sent_by_id", "neighbors", b"neighbors", "node_broadcast_interval_secs", b"node_broadcast_interval_secs", "node_id", b"node_id"]) -> None: ... - -global___NeighborInfo = NeighborInfo - -@typing_extensions.final -class Neighbor(google.protobuf.message.Message): - """ - A single edge in the mesh - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NODE_ID_FIELD_NUMBER: builtins.int - SNR_FIELD_NUMBER: builtins.int - LAST_RX_TIME_FIELD_NUMBER: builtins.int - NODE_BROADCAST_INTERVAL_SECS_FIELD_NUMBER: builtins.int - node_id: builtins.int - """ - Node ID of neighbor - """ - snr: builtins.float - """ - SNR of last heard message - """ - last_rx_time: builtins.int - """ - Reception time (in secs since 1970) of last message that was last sent by this ID. - Note: this is for local storage only and will not be sent out over the mesh. - """ - node_broadcast_interval_secs: builtins.int - """ - Broadcast interval of this neighbor (in seconds). - Note: this is for local storage only and will not be sent out over the mesh. - """ - def __init__( - self, - *, - node_id: builtins.int = ..., - snr: builtins.float = ..., - last_rx_time: builtins.int = ..., - node_broadcast_interval_secs: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["last_rx_time", b"last_rx_time", "node_broadcast_interval_secs", b"node_broadcast_interval_secs", "node_id", b"node_id", "snr", b"snr"]) -> None: ... - -global___Neighbor = Neighbor - -@typing_extensions.final -class DeviceMetadata(google.protobuf.message.Message): - """ - Device metadata response - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - FIRMWARE_VERSION_FIELD_NUMBER: builtins.int - DEVICE_STATE_VERSION_FIELD_NUMBER: builtins.int - CANSHUTDOWN_FIELD_NUMBER: builtins.int - HASWIFI_FIELD_NUMBER: builtins.int - HASBLUETOOTH_FIELD_NUMBER: builtins.int - HASETHERNET_FIELD_NUMBER: builtins.int - ROLE_FIELD_NUMBER: builtins.int - POSITION_FLAGS_FIELD_NUMBER: builtins.int - HW_MODEL_FIELD_NUMBER: builtins.int - HASREMOTEHARDWARE_FIELD_NUMBER: builtins.int - firmware_version: builtins.str - """ - Device firmware version string - """ - device_state_version: builtins.int - """ - Device state version - """ - canShutdown: builtins.bool - """ - Indicates whether the device can shutdown CPU natively or via power management chip - """ - hasWifi: builtins.bool - """ - Indicates that the device has native wifi capability - """ - hasBluetooth: builtins.bool - """ - Indicates that the device has native bluetooth capability - """ - hasEthernet: builtins.bool - """ - Indicates that the device has an ethernet peripheral - """ - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType - """ - Indicates that the device's role in the mesh - """ - position_flags: builtins.int - """ - Indicates the device's current enabled position flags - """ - hw_model: global___HardwareModel.ValueType - """ - Device hardware model - """ - hasRemoteHardware: builtins.bool - """ - Has Remote Hardware enabled - """ - def __init__( - self, - *, - firmware_version: builtins.str = ..., - device_state_version: builtins.int = ..., - canShutdown: builtins.bool = ..., - hasWifi: builtins.bool = ..., - hasBluetooth: builtins.bool = ..., - hasEthernet: builtins.bool = ..., - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType = ..., - position_flags: builtins.int = ..., - hw_model: global___HardwareModel.ValueType = ..., - hasRemoteHardware: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["canShutdown", b"canShutdown", "device_state_version", b"device_state_version", "firmware_version", b"firmware_version", "hasBluetooth", b"hasBluetooth", "hasEthernet", b"hasEthernet", "hasRemoteHardware", b"hasRemoteHardware", "hasWifi", b"hasWifi", "hw_model", b"hw_model", "position_flags", b"position_flags", "role", b"role"]) -> None: ... - -global___DeviceMetadata = DeviceMetadata - -@typing_extensions.final -class Heartbeat(google.protobuf.message.Message): - """ - A heartbeat message is sent to the node from the client to keep the connection alive. - This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - def __init__( - self, - ) -> None: ... - -global___Heartbeat = Heartbeat - -@typing_extensions.final -class NodeRemoteHardwarePin(google.protobuf.message.Message): - """ - RemoteHardwarePins associated with a node - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NODE_NUM_FIELD_NUMBER: builtins.int - PIN_FIELD_NUMBER: builtins.int - node_num: builtins.int - """ - The node_num exposing the available gpio pin - """ - @property - def pin(self) -> meshtastic.module_config_pb2.RemoteHardwarePin: - """ - The the available gpio pin for usage with RemoteHardware module - """ - def __init__( - self, - *, - node_num: builtins.int = ..., - pin: meshtastic.module_config_pb2.RemoteHardwarePin | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["pin", b"pin"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["node_num", b"node_num", "pin", b"pin"]) -> None: ... - -global___NodeRemoteHardwarePin = NodeRemoteHardwarePin - -@typing_extensions.final -class ChunkedPayload(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PAYLOAD_ID_FIELD_NUMBER: builtins.int - CHUNK_COUNT_FIELD_NUMBER: builtins.int - CHUNK_INDEX_FIELD_NUMBER: builtins.int - PAYLOAD_CHUNK_FIELD_NUMBER: builtins.int - payload_id: builtins.int - """ - The ID of the entire payload - """ - chunk_count: builtins.int - """ - The total number of chunks in the payload - """ - chunk_index: builtins.int - """ - The current chunk index in the total - """ - payload_chunk: builtins.bytes - """ - The binary data of the current chunk - """ - def __init__( - self, - *, - payload_id: builtins.int = ..., - chunk_count: builtins.int = ..., - chunk_index: builtins.int = ..., - payload_chunk: builtins.bytes = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["chunk_count", b"chunk_count", "chunk_index", b"chunk_index", "payload_chunk", b"payload_chunk", "payload_id", b"payload_id"]) -> None: ... - -global___ChunkedPayload = ChunkedPayload - -@typing_extensions.final -class resend_chunks(google.protobuf.message.Message): - """ - Wrapper message for broken repeated oneof support - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CHUNKS_FIELD_NUMBER: builtins.int - @property - def chunks(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... - def __init__( - self, - *, - chunks: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["chunks", b"chunks"]) -> None: ... - -global___resend_chunks = resend_chunks - -@typing_extensions.final -class ChunkedPayloadResponse(google.protobuf.message.Message): - """ - Responses to a ChunkedPayload request - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PAYLOAD_ID_FIELD_NUMBER: builtins.int - REQUEST_TRANSFER_FIELD_NUMBER: builtins.int - ACCEPT_TRANSFER_FIELD_NUMBER: builtins.int - RESEND_CHUNKS_FIELD_NUMBER: builtins.int - payload_id: builtins.int - """ - The ID of the entire payload - """ - request_transfer: builtins.bool - """ - Request to transfer chunked payload - """ - accept_transfer: builtins.bool - """ - Accept the transfer chunked payload - """ - @property - def resend_chunks(self) -> global___resend_chunks: - """ - Request missing indexes in the chunked payload - """ - def __init__( - self, - *, - payload_id: builtins.int = ..., - request_transfer: builtins.bool = ..., - accept_transfer: builtins.bool = ..., - resend_chunks: global___resend_chunks | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["accept_transfer", b"accept_transfer", "payload_variant", b"payload_variant", "request_transfer", b"request_transfer", "resend_chunks", b"resend_chunks"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["accept_transfer", b"accept_transfer", "payload_id", b"payload_id", "payload_variant", b"payload_variant", "request_transfer", b"request_transfer", "resend_chunks", b"resend_chunks"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["request_transfer", "accept_transfer", "resend_chunks"] | None: ... - -global___ChunkedPayloadResponse = ChunkedPayloadResponse diff --git a/meshtastic/module_config_pb2.py b/meshtastic/module_config_pb2.py deleted file mode 100644 index b1085e6..0000000 --- a/meshtastic/module_config_pb2.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/module_config.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/module_config.proto\x12\nmeshtastic\"\xd3\"\n\x0cModuleConfig\x12\x33\n\x04mqtt\x18\x01 \x01(\x0b\x32#.meshtastic.ModuleConfig.MQTTConfigH\x00\x12\x37\n\x06serial\x18\x02 \x01(\x0b\x32%.meshtastic.ModuleConfig.SerialConfigH\x00\x12T\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32\x33.meshtastic.ModuleConfig.ExternalNotificationConfigH\x00\x12\x44\n\rstore_forward\x18\x04 \x01(\x0b\x32+.meshtastic.ModuleConfig.StoreForwardConfigH\x00\x12>\n\nrange_test\x18\x05 \x01(\x0b\x32(.meshtastic.ModuleConfig.RangeTestConfigH\x00\x12=\n\ttelemetry\x18\x06 \x01(\x0b\x32(.meshtastic.ModuleConfig.TelemetryConfigH\x00\x12\x46\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32,.meshtastic.ModuleConfig.CannedMessageConfigH\x00\x12\x35\n\x05\x61udio\x18\x08 \x01(\x0b\x32$.meshtastic.ModuleConfig.AudioConfigH\x00\x12H\n\x0fremote_hardware\x18\t \x01(\x0b\x32-.meshtastic.ModuleConfig.RemoteHardwareConfigH\x00\x12\x44\n\rneighbor_info\x18\n \x01(\x0b\x32+.meshtastic.ModuleConfig.NeighborInfoConfigH\x00\x12J\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32..meshtastic.ModuleConfig.AmbientLightingConfigH\x00\x12J\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32..meshtastic.ModuleConfig.DetectionSensorConfigH\x00\x12?\n\npaxcounter\x18\r \x01(\x0b\x32).meshtastic.ModuleConfig.PaxcounterConfigH\x00\x1a\xb0\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12G\n\x13map_report_settings\x18\x0b \x01(\x0b\x32*.meshtastic.ModuleConfig.MapReportSettings\x1aN\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x1a\x82\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12\x35\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32\x1d.meshtastic.RemoteHardwarePin\x1a>\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x1a\xd2\x01\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12 \n\x18\x64\x65tection_triggered_high\x18\x07 \x01(\x08\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\x1a\xe4\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12@\n\x07\x62itrate\x18\x03 \x01(\x0e\x32/.meshtastic.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xe4\x04\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12?\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32\x31.meshtastic.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12?\n\x04mode\x18\x07 \x01(\x0e\x32\x31.meshtastic.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"U\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x84\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x1a@\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x1a\xe6\x02\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x1a\xd6\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12Y\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12Z\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12\\\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x0f\n\x07\x65nabled\x18\t \x01(\x08\x12\x1a\n\x12\x61llow_input_source\x18\n \x01(\t\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\rB\x11\n\x0fpayload_variant\"d\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12/\n\x04type\x18\x03 \x01(\x0e\x32!.meshtastic.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42g\n\x13\x63om.geeksville.meshB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.module_config_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\022ModuleConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _REMOTEHARDWAREPINTYPE._serialized_start=4586 - _REMOTEHARDWAREPINTYPE._serialized_end=4659 - _MODULECONFIG._serialized_start=47 - _MODULECONFIG._serialized_end=4482 - _MODULECONFIG_MQTTCONFIG._serialized_start=945 - _MODULECONFIG_MQTTCONFIG._serialized_end=1249 - _MODULECONFIG_MAPREPORTSETTINGS._serialized_start=1251 - _MODULECONFIG_MAPREPORTSETTINGS._serialized_end=1329 - _MODULECONFIG_REMOTEHARDWARECONFIG._serialized_start=1332 - _MODULECONFIG_REMOTEHARDWARECONFIG._serialized_end=1462 - _MODULECONFIG_NEIGHBORINFOCONFIG._serialized_start=1464 - _MODULECONFIG_NEIGHBORINFOCONFIG._serialized_end=1526 - _MODULECONFIG_DETECTIONSENSORCONFIG._serialized_start=1529 - _MODULECONFIG_DETECTIONSENSORCONFIG._serialized_end=1739 - _MODULECONFIG_AUDIOCONFIG._serialized_start=1742 - _MODULECONFIG_AUDIOCONFIG._serialized_end=2098 - _MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_start=1931 - _MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_end=2098 - _MODULECONFIG_PAXCOUNTERCONFIG._serialized_start=2100 - _MODULECONFIG_PAXCOUNTERCONFIG._serialized_end=2218 - _MODULECONFIG_SERIALCONFIG._serialized_start=2221 - _MODULECONFIG_SERIALCONFIG._serialized_end=2833 - _MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_start=2480 - _MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_end=2746 - _MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_start=2748 - _MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_end=2833 - _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_start=2836 - _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_end=3197 - _MODULECONFIG_STOREFORWARDCONFIG._serialized_start=3200 - _MODULECONFIG_STOREFORWARDCONFIG._serialized_end=3332 - _MODULECONFIG_RANGETESTCONFIG._serialized_start=3334 - _MODULECONFIG_RANGETESTCONFIG._serialized_end=3398 - _MODULECONFIG_TELEMETRYCONFIG._serialized_start=3401 - _MODULECONFIG_TELEMETRYCONFIG._serialized_end=3759 - _MODULECONFIG_CANNEDMESSAGECONFIG._serialized_start=3762 - _MODULECONFIG_CANNEDMESSAGECONFIG._serialized_end=4360 - _MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_start=4261 - _MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_end=4360 - _MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_start=4362 - _MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_end=4463 - _REMOTEHARDWAREPIN._serialized_start=4484 - _REMOTEHARDWAREPIN._serialized_end=4584 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/module_config_pb2.pyi b/meshtastic/module_config_pb2.pyi deleted file mode 100644 index 67bb608..0000000 --- a/meshtastic/module_config_pb2.pyi +++ /dev/null @@ -1,1184 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -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 _RemoteHardwarePinType: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _RemoteHardwarePinTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RemoteHardwarePinType.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNKNOWN: _RemoteHardwarePinType.ValueType # 0 - """ - Unset/unused - """ - DIGITAL_READ: _RemoteHardwarePinType.ValueType # 1 - """ - GPIO pin can be read (if it is high / low) - """ - DIGITAL_WRITE: _RemoteHardwarePinType.ValueType # 2 - """ - GPIO pin can be written to (high / low) - """ - -class RemoteHardwarePinType(_RemoteHardwarePinType, metaclass=_RemoteHardwarePinTypeEnumTypeWrapper): ... - -UNKNOWN: RemoteHardwarePinType.ValueType # 0 -""" -Unset/unused -""" -DIGITAL_READ: RemoteHardwarePinType.ValueType # 1 -""" -GPIO pin can be read (if it is high / low) -""" -DIGITAL_WRITE: RemoteHardwarePinType.ValueType # 2 -""" -GPIO pin can be written to (high / low) -""" -global___RemoteHardwarePinType = RemoteHardwarePinType - -@typing_extensions.final -class ModuleConfig(google.protobuf.message.Message): - """ - Module Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - @typing_extensions.final - class MQTTConfig(google.protobuf.message.Message): - """ - MQTT Client Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - ADDRESS_FIELD_NUMBER: builtins.int - USERNAME_FIELD_NUMBER: builtins.int - PASSWORD_FIELD_NUMBER: builtins.int - ENCRYPTION_ENABLED_FIELD_NUMBER: builtins.int - JSON_ENABLED_FIELD_NUMBER: builtins.int - TLS_ENABLED_FIELD_NUMBER: builtins.int - ROOT_FIELD_NUMBER: builtins.int - PROXY_TO_CLIENT_ENABLED_FIELD_NUMBER: builtins.int - MAP_REPORTING_ENABLED_FIELD_NUMBER: builtins.int - MAP_REPORT_SETTINGS_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - If a meshtastic node is able to reach the internet it will normally attempt to gateway any channels that are marked as - is_uplink_enabled or is_downlink_enabled. - """ - address: builtins.str - """ - The server to use for our MQTT global message gateway feature. - If not set, the default server will be used - """ - username: builtins.str - """ - MQTT username to use (most useful for a custom MQTT server). - If using a custom server, this will be honoured even if empty. - If using the default server, this will only be honoured if set, otherwise the device will use the default username - """ - password: builtins.str - """ - MQTT password to use (most useful for a custom MQTT server). - If using a custom server, this will be honoured even if empty. - If using the default server, this will only be honoured if set, otherwise the device will use the default password - """ - encryption_enabled: builtins.bool - """ - Whether to send encrypted or decrypted packets to MQTT. - This parameter is only honoured if you also set server - (the default official mqtt.meshtastic.org server can handle encrypted packets) - Decrypted packets may be useful for external systems that want to consume meshtastic packets - """ - json_enabled: builtins.bool - """ - Whether to send / consume json packets on MQTT - """ - tls_enabled: builtins.bool - """ - If true, we attempt to establish a secure connection using TLS - """ - root: builtins.str - """ - The root topic to use for MQTT messages. Default is "msh". - This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs - """ - proxy_to_client_enabled: builtins.bool - """ - If true, we can use the connected phone / client to proxy messages to MQTT instead of a direct connection - """ - map_reporting_enabled: builtins.bool - """ - If true, we will periodically report unencrypted information about our node to a map via MQTT - """ - @property - def map_report_settings(self) -> global___ModuleConfig.MapReportSettings: - """ - Settings for reporting information about our node to a map via MQTT - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - address: builtins.str = ..., - username: builtins.str = ..., - password: builtins.str = ..., - encryption_enabled: builtins.bool = ..., - json_enabled: builtins.bool = ..., - tls_enabled: builtins.bool = ..., - root: builtins.str = ..., - proxy_to_client_enabled: builtins.bool = ..., - map_reporting_enabled: builtins.bool = ..., - map_report_settings: global___ModuleConfig.MapReportSettings | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["map_report_settings", b"map_report_settings"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "enabled", b"enabled", "encryption_enabled", b"encryption_enabled", "json_enabled", b"json_enabled", "map_report_settings", b"map_report_settings", "map_reporting_enabled", b"map_reporting_enabled", "password", b"password", "proxy_to_client_enabled", b"proxy_to_client_enabled", "root", b"root", "tls_enabled", b"tls_enabled", "username", b"username"]) -> None: ... - - @typing_extensions.final - class MapReportSettings(google.protobuf.message.Message): - """ - Settings for reporting unencrypted information about our node to a map via MQTT - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PUBLISH_INTERVAL_SECS_FIELD_NUMBER: builtins.int - POSITION_PRECISION_FIELD_NUMBER: builtins.int - publish_interval_secs: builtins.int - """ - How often we should report our info to the map (in seconds) - """ - position_precision: builtins.int - """ - Bits of precision for the location sent (default of 32 is full precision). - """ - def __init__( - self, - *, - publish_interval_secs: builtins.int = ..., - position_precision: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["position_precision", b"position_precision", "publish_interval_secs", b"publish_interval_secs"]) -> None: ... - - @typing_extensions.final - class RemoteHardwareConfig(google.protobuf.message.Message): - """ - RemoteHardwareModule Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - ALLOW_UNDEFINED_PIN_ACCESS_FIELD_NUMBER: builtins.int - AVAILABLE_PINS_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Whether the Module is enabled - """ - allow_undefined_pin_access: builtins.bool - """ - Whether the Module allows consumers to read / write to pins not defined in available_pins - """ - @property - def available_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___RemoteHardwarePin]: - """ - Exposes the available pins to the mesh for reading and writing - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - allow_undefined_pin_access: builtins.bool = ..., - available_pins: collections.abc.Iterable[global___RemoteHardwarePin] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_undefined_pin_access", b"allow_undefined_pin_access", "available_pins", b"available_pins", "enabled", b"enabled"]) -> None: ... - - @typing_extensions.final - class NeighborInfoConfig(google.protobuf.message.Message): - """ - NeighborInfoModule Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Whether the Module is enabled - """ - update_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - Neighbor Info to the mesh - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - update_interval: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["enabled", b"enabled", "update_interval", b"update_interval"]) -> None: ... - - @typing_extensions.final - class DetectionSensorConfig(google.protobuf.message.Message): - """ - Detection Sensor Module Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - MINIMUM_BROADCAST_SECS_FIELD_NUMBER: builtins.int - STATE_BROADCAST_SECS_FIELD_NUMBER: builtins.int - SEND_BELL_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - MONITOR_PIN_FIELD_NUMBER: builtins.int - DETECTION_TRIGGERED_HIGH_FIELD_NUMBER: builtins.int - USE_PULLUP_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Whether the Module is enabled - """ - minimum_broadcast_secs: builtins.int - """ - Interval in seconds of how often we can send a message to the mesh when a state change is detected - """ - state_broadcast_secs: builtins.int - """ - Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes - When set to 0, only state changes will be broadcasted - Works as a sort of status heartbeat for peace of mind - """ - send_bell: builtins.bool - """ - Send ASCII bell with alert message - Useful for triggering ext. notification on bell - """ - name: builtins.str - """ - Friendly name used to format message sent to mesh - Example: A name "Motion" would result in a message "Motion detected" - Maximum length of 20 characters - """ - monitor_pin: builtins.int - """ - GPIO pin to monitor for state changes - """ - detection_triggered_high: builtins.bool - """ - Whether or not the GPIO pin state detection is triggered on HIGH (1) - Otherwise LOW (0) - """ - use_pullup: builtins.bool - """ - Whether or not use INPUT_PULLUP mode for GPIO pin - Only applicable if the board uses pull-up resistors on the pin - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - minimum_broadcast_secs: builtins.int = ..., - state_broadcast_secs: builtins.int = ..., - send_bell: builtins.bool = ..., - name: builtins.str = ..., - monitor_pin: builtins.int = ..., - detection_triggered_high: builtins.bool = ..., - use_pullup: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["detection_triggered_high", b"detection_triggered_high", "enabled", b"enabled", "minimum_broadcast_secs", b"minimum_broadcast_secs", "monitor_pin", b"monitor_pin", "name", b"name", "send_bell", b"send_bell", "state_broadcast_secs", b"state_broadcast_secs", "use_pullup", b"use_pullup"]) -> None: ... - - @typing_extensions.final - class AudioConfig(google.protobuf.message.Message): - """ - Audio Config for codec2 voice - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Audio_Baud: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _Audio_BaudEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.AudioConfig._Audio_Baud.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - CODEC2_DEFAULT: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 0 - CODEC2_3200: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 1 - CODEC2_2400: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 2 - CODEC2_1600: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 3 - CODEC2_1400: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 4 - CODEC2_1300: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 5 - CODEC2_1200: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 6 - CODEC2_700: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 7 - CODEC2_700B: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 8 - - class Audio_Baud(_Audio_Baud, metaclass=_Audio_BaudEnumTypeWrapper): - """ - Baudrate for codec2 voice - """ - - CODEC2_DEFAULT: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 0 - CODEC2_3200: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 1 - CODEC2_2400: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 2 - CODEC2_1600: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 3 - CODEC2_1400: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 4 - CODEC2_1300: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 5 - CODEC2_1200: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 6 - CODEC2_700: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 7 - CODEC2_700B: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 8 - - CODEC2_ENABLED_FIELD_NUMBER: builtins.int - PTT_PIN_FIELD_NUMBER: builtins.int - BITRATE_FIELD_NUMBER: builtins.int - I2S_WS_FIELD_NUMBER: builtins.int - I2S_SD_FIELD_NUMBER: builtins.int - I2S_DIN_FIELD_NUMBER: builtins.int - I2S_SCK_FIELD_NUMBER: builtins.int - codec2_enabled: builtins.bool - """ - Whether Audio is enabled - """ - ptt_pin: builtins.int - """ - PTT Pin - """ - bitrate: global___ModuleConfig.AudioConfig.Audio_Baud.ValueType - """ - The audio sample rate to use for codec2 - """ - i2s_ws: builtins.int - """ - I2S Word Select - """ - i2s_sd: builtins.int - """ - I2S Data IN - """ - i2s_din: builtins.int - """ - I2S Data OUT - """ - i2s_sck: builtins.int - """ - I2S Clock - """ - def __init__( - self, - *, - codec2_enabled: builtins.bool = ..., - ptt_pin: builtins.int = ..., - bitrate: global___ModuleConfig.AudioConfig.Audio_Baud.ValueType = ..., - i2s_ws: builtins.int = ..., - i2s_sd: builtins.int = ..., - i2s_din: builtins.int = ..., - i2s_sck: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["bitrate", b"bitrate", "codec2_enabled", b"codec2_enabled", "i2s_din", b"i2s_din", "i2s_sck", b"i2s_sck", "i2s_sd", b"i2s_sd", "i2s_ws", b"i2s_ws", "ptt_pin", b"ptt_pin"]) -> None: ... - - @typing_extensions.final - class PaxcounterConfig(google.protobuf.message.Message): - """ - Config for the Paxcounter Module - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - PAXCOUNTER_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - WIFI_THRESHOLD_FIELD_NUMBER: builtins.int - BLE_THRESHOLD_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Enable the Paxcounter Module - """ - paxcounter_update_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - metrics to the mesh - """ - wifi_threshold: builtins.int - """ - WiFi RSSI threshold. Defaults to -80 - """ - ble_threshold: builtins.int - """ - BLE RSSI threshold. Defaults to -80 - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - paxcounter_update_interval: builtins.int = ..., - wifi_threshold: builtins.int = ..., - ble_threshold: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["ble_threshold", b"ble_threshold", "enabled", b"enabled", "paxcounter_update_interval", b"paxcounter_update_interval", "wifi_threshold", b"wifi_threshold"]) -> None: ... - - @typing_extensions.final - class SerialConfig(google.protobuf.message.Message): - """ - Serial Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Serial_Baud: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _Serial_BaudEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.SerialConfig._Serial_Baud.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - BAUD_DEFAULT: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 0 - BAUD_110: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 1 - BAUD_300: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 2 - BAUD_600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 3 - BAUD_1200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 4 - BAUD_2400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 5 - BAUD_4800: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 6 - BAUD_9600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 7 - BAUD_19200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 8 - BAUD_38400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 9 - BAUD_57600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 10 - BAUD_115200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 11 - BAUD_230400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 12 - BAUD_460800: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 13 - BAUD_576000: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 14 - BAUD_921600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 15 - - class Serial_Baud(_Serial_Baud, metaclass=_Serial_BaudEnumTypeWrapper): - """ - TODO: REPLACE - """ - - BAUD_DEFAULT: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 0 - BAUD_110: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 1 - BAUD_300: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 2 - BAUD_600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 3 - BAUD_1200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 4 - BAUD_2400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 5 - BAUD_4800: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 6 - BAUD_9600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 7 - BAUD_19200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 8 - BAUD_38400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 9 - BAUD_57600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 10 - BAUD_115200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 11 - BAUD_230400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 12 - BAUD_460800: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 13 - BAUD_576000: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 14 - BAUD_921600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 15 - - class _Serial_Mode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _Serial_ModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.SerialConfig._Serial_Mode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DEFAULT: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 0 - SIMPLE: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 1 - PROTO: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 2 - TEXTMSG: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 3 - NMEA: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 4 - CALTOPO: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 5 - """NMEA messages specifically tailored for CalTopo""" - - class Serial_Mode(_Serial_Mode, metaclass=_Serial_ModeEnumTypeWrapper): - """ - TODO: REPLACE - """ - - DEFAULT: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 0 - SIMPLE: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 1 - PROTO: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 2 - TEXTMSG: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 3 - NMEA: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 4 - CALTOPO: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 5 - """NMEA messages specifically tailored for CalTopo""" - - ENABLED_FIELD_NUMBER: builtins.int - ECHO_FIELD_NUMBER: builtins.int - RXD_FIELD_NUMBER: builtins.int - TXD_FIELD_NUMBER: builtins.int - BAUD_FIELD_NUMBER: builtins.int - TIMEOUT_FIELD_NUMBER: builtins.int - MODE_FIELD_NUMBER: builtins.int - OVERRIDE_CONSOLE_SERIAL_PORT_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Preferences for the SerialModule - """ - echo: builtins.bool - """ - TODO: REPLACE - """ - rxd: builtins.int - """ - RX pin (should match Arduino gpio pin number) - """ - txd: builtins.int - """ - TX pin (should match Arduino gpio pin number) - """ - baud: global___ModuleConfig.SerialConfig.Serial_Baud.ValueType - """ - Serial baud rate - """ - timeout: builtins.int - """ - TODO: REPLACE - """ - mode: global___ModuleConfig.SerialConfig.Serial_Mode.ValueType - """ - Mode for serial module operation - """ - override_console_serial_port: builtins.bool - """ - Overrides the platform's defacto Serial port instance to use with Serial module config settings - This is currently only usable in output modes like NMEA / CalTopo and may behave strangely or not work at all in other modes - Existing logging over the Serial Console will still be present - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - echo: builtins.bool = ..., - rxd: builtins.int = ..., - txd: builtins.int = ..., - baud: global___ModuleConfig.SerialConfig.Serial_Baud.ValueType = ..., - timeout: builtins.int = ..., - mode: global___ModuleConfig.SerialConfig.Serial_Mode.ValueType = ..., - override_console_serial_port: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["baud", b"baud", "echo", b"echo", "enabled", b"enabled", "mode", b"mode", "override_console_serial_port", b"override_console_serial_port", "rxd", b"rxd", "timeout", b"timeout", "txd", b"txd"]) -> None: ... - - @typing_extensions.final - class ExternalNotificationConfig(google.protobuf.message.Message): - """ - External Notifications Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - OUTPUT_MS_FIELD_NUMBER: builtins.int - OUTPUT_FIELD_NUMBER: builtins.int - OUTPUT_VIBRA_FIELD_NUMBER: builtins.int - OUTPUT_BUZZER_FIELD_NUMBER: builtins.int - ACTIVE_FIELD_NUMBER: builtins.int - ALERT_MESSAGE_FIELD_NUMBER: builtins.int - ALERT_MESSAGE_VIBRA_FIELD_NUMBER: builtins.int - ALERT_MESSAGE_BUZZER_FIELD_NUMBER: builtins.int - ALERT_BELL_FIELD_NUMBER: builtins.int - ALERT_BELL_VIBRA_FIELD_NUMBER: builtins.int - ALERT_BELL_BUZZER_FIELD_NUMBER: builtins.int - USE_PWM_FIELD_NUMBER: builtins.int - NAG_TIMEOUT_FIELD_NUMBER: builtins.int - USE_I2S_AS_BUZZER_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Enable the ExternalNotificationModule - """ - output_ms: builtins.int - """ - When using in On/Off mode, keep the output on for this many - milliseconds. Default 1000ms (1 second). - """ - output: builtins.int - """ - Define the output pin GPIO setting Defaults to - EXT_NOTIFY_OUT if set for the board. - In standalone devices this pin should drive the LED to match the UI. - """ - output_vibra: builtins.int - """ - Optional: Define a secondary output pin for a vibra motor - This is used in standalone devices to match the UI. - """ - output_buzzer: builtins.int - """ - Optional: Define a tertiary output pin for an active buzzer - This is used in standalone devices to to match the UI. - """ - active: builtins.bool - """ - IF this is true, the 'output' Pin will be pulled active high, false - means active low. - """ - alert_message: builtins.bool - """ - True: Alert when a text message arrives (output) - """ - alert_message_vibra: builtins.bool - """ - True: Alert when a text message arrives (output_vibra) - """ - alert_message_buzzer: builtins.bool - """ - True: Alert when a text message arrives (output_buzzer) - """ - alert_bell: builtins.bool - """ - True: Alert when the bell character is received (output) - """ - alert_bell_vibra: builtins.bool - """ - True: Alert when the bell character is received (output_vibra) - """ - alert_bell_buzzer: builtins.bool - """ - True: Alert when the bell character is received (output_buzzer) - """ - use_pwm: builtins.bool - """ - use a PWM output instead of a simple on/off output. This will ignore - the 'output', 'output_ms' and 'active' settings and use the - device.buzzer_gpio instead. - """ - nag_timeout: builtins.int - """ - The notification will toggle with 'output_ms' for this time of seconds. - Default is 0 which means don't repeat at all. 60 would mean blink - and/or beep for 60 seconds - """ - use_i2s_as_buzzer: builtins.bool - """ - When true, enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer - T-Watch S3 and T-Deck for example have this capability - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - output_ms: builtins.int = ..., - output: builtins.int = ..., - output_vibra: builtins.int = ..., - output_buzzer: builtins.int = ..., - active: builtins.bool = ..., - alert_message: builtins.bool = ..., - alert_message_vibra: builtins.bool = ..., - alert_message_buzzer: builtins.bool = ..., - alert_bell: builtins.bool = ..., - alert_bell_vibra: builtins.bool = ..., - alert_bell_buzzer: builtins.bool = ..., - use_pwm: builtins.bool = ..., - nag_timeout: builtins.int = ..., - use_i2s_as_buzzer: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["active", b"active", "alert_bell", b"alert_bell", "alert_bell_buzzer", b"alert_bell_buzzer", "alert_bell_vibra", b"alert_bell_vibra", "alert_message", b"alert_message", "alert_message_buzzer", b"alert_message_buzzer", "alert_message_vibra", b"alert_message_vibra", "enabled", b"enabled", "nag_timeout", b"nag_timeout", "output", b"output", "output_buzzer", b"output_buzzer", "output_ms", b"output_ms", "output_vibra", b"output_vibra", "use_i2s_as_buzzer", b"use_i2s_as_buzzer", "use_pwm", b"use_pwm"]) -> None: ... - - @typing_extensions.final - class StoreForwardConfig(google.protobuf.message.Message): - """ - Store and Forward Module Config - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - HEARTBEAT_FIELD_NUMBER: builtins.int - RECORDS_FIELD_NUMBER: builtins.int - HISTORY_RETURN_MAX_FIELD_NUMBER: builtins.int - HISTORY_RETURN_WINDOW_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Enable the Store and Forward Module - """ - heartbeat: builtins.bool - """ - TODO: REPLACE - """ - records: builtins.int - """ - TODO: REPLACE - """ - history_return_max: builtins.int - """ - TODO: REPLACE - """ - history_return_window: builtins.int - """ - TODO: REPLACE - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - heartbeat: builtins.bool = ..., - records: builtins.int = ..., - history_return_max: builtins.int = ..., - history_return_window: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["enabled", b"enabled", "heartbeat", b"heartbeat", "history_return_max", b"history_return_max", "history_return_window", b"history_return_window", "records", b"records"]) -> None: ... - - @typing_extensions.final - class RangeTestConfig(google.protobuf.message.Message): - """ - Preferences for the RangeTestModule - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ENABLED_FIELD_NUMBER: builtins.int - SENDER_FIELD_NUMBER: builtins.int - SAVE_FIELD_NUMBER: builtins.int - enabled: builtins.bool - """ - Enable the Range Test Module - """ - sender: builtins.int - """ - Send out range test messages from this node - """ - save: builtins.bool - """ - Bool value indicating that this node should save a RangeTest.csv file. - ESP32 Only - """ - def __init__( - self, - *, - enabled: builtins.bool = ..., - sender: builtins.int = ..., - save: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["enabled", b"enabled", "save", b"save", "sender", b"sender"]) -> None: ... - - @typing_extensions.final - class TelemetryConfig(google.protobuf.message.Message): - """ - Configuration for both device and environment metrics - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DEVICE_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - ENVIRONMENT_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - ENVIRONMENT_MEASUREMENT_ENABLED_FIELD_NUMBER: builtins.int - ENVIRONMENT_SCREEN_ENABLED_FIELD_NUMBER: builtins.int - ENVIRONMENT_DISPLAY_FAHRENHEIT_FIELD_NUMBER: builtins.int - AIR_QUALITY_ENABLED_FIELD_NUMBER: builtins.int - AIR_QUALITY_INTERVAL_FIELD_NUMBER: builtins.int - POWER_MEASUREMENT_ENABLED_FIELD_NUMBER: builtins.int - POWER_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int - POWER_SCREEN_ENABLED_FIELD_NUMBER: builtins.int - device_update_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - device metrics to the mesh - """ - environment_update_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - environment measurements to the mesh - """ - environment_measurement_enabled: builtins.bool - """ - Preferences for the Telemetry Module (Environment) - Enable/Disable the telemetry measurement module measurement collection - """ - environment_screen_enabled: builtins.bool - """ - Enable/Disable the telemetry measurement module on-device display - """ - environment_display_fahrenheit: builtins.bool - """ - We'll always read the sensor in Celsius, but sometimes we might want to - display the results in Fahrenheit as a "user preference". - """ - air_quality_enabled: builtins.bool - """ - Enable/Disable the air quality metrics - """ - air_quality_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - air quality metrics to the mesh - """ - power_measurement_enabled: builtins.bool - """ - Interval in seconds of how often we should try to send our - air quality metrics to the mesh - """ - power_update_interval: builtins.int - """ - Interval in seconds of how often we should try to send our - air quality metrics to the mesh - """ - power_screen_enabled: builtins.bool - """ - Interval in seconds of how often we should try to send our - air quality metrics to the mesh - """ - def __init__( - self, - *, - device_update_interval: builtins.int = ..., - environment_update_interval: builtins.int = ..., - environment_measurement_enabled: builtins.bool = ..., - environment_screen_enabled: builtins.bool = ..., - environment_display_fahrenheit: builtins.bool = ..., - air_quality_enabled: builtins.bool = ..., - air_quality_interval: builtins.int = ..., - power_measurement_enabled: builtins.bool = ..., - power_update_interval: builtins.int = ..., - power_screen_enabled: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.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", "power_measurement_enabled", b"power_measurement_enabled", "power_screen_enabled", b"power_screen_enabled", "power_update_interval", b"power_update_interval"]) -> None: ... - - @typing_extensions.final - class CannedMessageConfig(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _InputEventChar: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _InputEventCharEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.CannedMessageConfig._InputEventChar.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - NONE: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 0 - """ - TODO: REPLACE - """ - UP: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 17 - """ - TODO: REPLACE - """ - DOWN: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 18 - """ - TODO: REPLACE - """ - LEFT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 19 - """ - TODO: REPLACE - """ - RIGHT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 20 - """ - TODO: REPLACE - """ - SELECT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 10 - """ - '\\n' - """ - BACK: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 27 - """ - TODO: REPLACE - """ - CANCEL: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 24 - """ - TODO: REPLACE - """ - - class InputEventChar(_InputEventChar, metaclass=_InputEventCharEnumTypeWrapper): - """ - TODO: REPLACE - """ - - NONE: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 0 - """ - TODO: REPLACE - """ - UP: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 17 - """ - TODO: REPLACE - """ - DOWN: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 18 - """ - TODO: REPLACE - """ - LEFT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 19 - """ - TODO: REPLACE - """ - RIGHT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 20 - """ - TODO: REPLACE - """ - SELECT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 10 - """ - '\\n' - """ - BACK: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 27 - """ - TODO: REPLACE - """ - CANCEL: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 24 - """ - TODO: REPLACE - """ - - ROTARY1_ENABLED_FIELD_NUMBER: builtins.int - INPUTBROKER_PIN_A_FIELD_NUMBER: builtins.int - INPUTBROKER_PIN_B_FIELD_NUMBER: builtins.int - INPUTBROKER_PIN_PRESS_FIELD_NUMBER: builtins.int - INPUTBROKER_EVENT_CW_FIELD_NUMBER: builtins.int - INPUTBROKER_EVENT_CCW_FIELD_NUMBER: builtins.int - INPUTBROKER_EVENT_PRESS_FIELD_NUMBER: builtins.int - UPDOWN1_ENABLED_FIELD_NUMBER: builtins.int - ENABLED_FIELD_NUMBER: builtins.int - ALLOW_INPUT_SOURCE_FIELD_NUMBER: builtins.int - SEND_BELL_FIELD_NUMBER: builtins.int - rotary1_enabled: builtins.bool - """ - Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. - """ - inputbroker_pin_a: builtins.int - """ - GPIO pin for rotary encoder A port. - """ - inputbroker_pin_b: builtins.int - """ - GPIO pin for rotary encoder B port. - """ - inputbroker_pin_press: builtins.int - """ - GPIO pin for rotary encoder Press port. - """ - inputbroker_event_cw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType - """ - Generate input event on CW of this kind. - """ - inputbroker_event_ccw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType - """ - Generate input event on CCW of this kind. - """ - inputbroker_event_press: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType - """ - Generate input event on Press of this kind. - """ - updown1_enabled: builtins.bool - """ - Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker. - """ - enabled: builtins.bool - """ - Enable/disable CannedMessageModule. - """ - allow_input_source: builtins.str - """ - Input event origin accepted by the canned message module. - Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any" - """ - send_bell: builtins.bool - """ - CannedMessageModule also sends a bell character with the messages. - ExternalNotificationModule can benefit from this feature. - """ - def __init__( - self, - *, - rotary1_enabled: builtins.bool = ..., - inputbroker_pin_a: builtins.int = ..., - inputbroker_pin_b: builtins.int = ..., - inputbroker_pin_press: builtins.int = ..., - inputbroker_event_cw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., - inputbroker_event_ccw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., - inputbroker_event_press: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., - updown1_enabled: builtins.bool = ..., - enabled: builtins.bool = ..., - allow_input_source: builtins.str = ..., - send_bell: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_input_source", b"allow_input_source", "enabled", b"enabled", "inputbroker_event_ccw", b"inputbroker_event_ccw", "inputbroker_event_cw", b"inputbroker_event_cw", "inputbroker_event_press", b"inputbroker_event_press", "inputbroker_pin_a", b"inputbroker_pin_a", "inputbroker_pin_b", b"inputbroker_pin_b", "inputbroker_pin_press", b"inputbroker_pin_press", "rotary1_enabled", b"rotary1_enabled", "send_bell", b"send_bell", "updown1_enabled", b"updown1_enabled"]) -> None: ... - - @typing_extensions.final - class AmbientLightingConfig(google.protobuf.message.Message): - """ - Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. - Initially created for the RAK14001 RGB LED module. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LED_STATE_FIELD_NUMBER: builtins.int - CURRENT_FIELD_NUMBER: builtins.int - RED_FIELD_NUMBER: builtins.int - GREEN_FIELD_NUMBER: builtins.int - BLUE_FIELD_NUMBER: builtins.int - led_state: builtins.bool - """ - Sets LED to on or off. - """ - current: builtins.int - """ - Sets the current for the LED output. Default is 10. - """ - red: builtins.int - """ - Sets the red LED level. Values are 0-255. - """ - green: builtins.int - """ - Sets the green LED level. Values are 0-255. - """ - blue: builtins.int - """ - Sets the blue LED level. Values are 0-255. - """ - def __init__( - self, - *, - led_state: builtins.bool = ..., - current: builtins.int = ..., - red: builtins.int = ..., - green: builtins.int = ..., - blue: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["blue", b"blue", "current", b"current", "green", b"green", "led_state", b"led_state", "red", b"red"]) -> None: ... - - MQTT_FIELD_NUMBER: builtins.int - SERIAL_FIELD_NUMBER: builtins.int - EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int - STORE_FORWARD_FIELD_NUMBER: builtins.int - RANGE_TEST_FIELD_NUMBER: builtins.int - TELEMETRY_FIELD_NUMBER: builtins.int - CANNED_MESSAGE_FIELD_NUMBER: builtins.int - AUDIO_FIELD_NUMBER: builtins.int - REMOTE_HARDWARE_FIELD_NUMBER: builtins.int - NEIGHBOR_INFO_FIELD_NUMBER: builtins.int - AMBIENT_LIGHTING_FIELD_NUMBER: builtins.int - DETECTION_SENSOR_FIELD_NUMBER: builtins.int - PAXCOUNTER_FIELD_NUMBER: builtins.int - @property - def mqtt(self) -> global___ModuleConfig.MQTTConfig: - """ - TODO: REPLACE - """ - @property - def serial(self) -> global___ModuleConfig.SerialConfig: - """ - TODO: REPLACE - """ - @property - def external_notification(self) -> global___ModuleConfig.ExternalNotificationConfig: - """ - TODO: REPLACE - """ - @property - def store_forward(self) -> global___ModuleConfig.StoreForwardConfig: - """ - TODO: REPLACE - """ - @property - def range_test(self) -> global___ModuleConfig.RangeTestConfig: - """ - TODO: REPLACE - """ - @property - def telemetry(self) -> global___ModuleConfig.TelemetryConfig: - """ - TODO: REPLACE - """ - @property - def canned_message(self) -> global___ModuleConfig.CannedMessageConfig: - """ - TODO: REPLACE - """ - @property - def audio(self) -> global___ModuleConfig.AudioConfig: - """ - TODO: REPLACE - """ - @property - def remote_hardware(self) -> global___ModuleConfig.RemoteHardwareConfig: - """ - TODO: REPLACE - """ - @property - def neighbor_info(self) -> global___ModuleConfig.NeighborInfoConfig: - """ - TODO: REPLACE - """ - @property - def ambient_lighting(self) -> global___ModuleConfig.AmbientLightingConfig: - """ - TODO: REPLACE - """ - @property - def detection_sensor(self) -> global___ModuleConfig.DetectionSensorConfig: - """ - TODO: REPLACE - """ - @property - def paxcounter(self) -> global___ModuleConfig.PaxcounterConfig: - """ - TODO: REPLACE - """ - def __init__( - self, - *, - mqtt: global___ModuleConfig.MQTTConfig | None = ..., - serial: global___ModuleConfig.SerialConfig | None = ..., - external_notification: global___ModuleConfig.ExternalNotificationConfig | None = ..., - store_forward: global___ModuleConfig.StoreForwardConfig | None = ..., - range_test: global___ModuleConfig.RangeTestConfig | None = ..., - telemetry: global___ModuleConfig.TelemetryConfig | None = ..., - canned_message: global___ModuleConfig.CannedMessageConfig | None = ..., - audio: global___ModuleConfig.AudioConfig | None = ..., - remote_hardware: global___ModuleConfig.RemoteHardwareConfig | None = ..., - neighbor_info: global___ModuleConfig.NeighborInfoConfig | None = ..., - ambient_lighting: global___ModuleConfig.AmbientLightingConfig | None = ..., - detection_sensor: global___ModuleConfig.DetectionSensorConfig | None = ..., - paxcounter: global___ModuleConfig.PaxcounterConfig | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["payload_variant", b"payload_variant"]) -> typing_extensions.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter"] | None: ... - -global___ModuleConfig = ModuleConfig - -@typing_extensions.final -class RemoteHardwarePin(google.protobuf.message.Message): - """ - A GPIO pin definition for remote hardware module - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - GPIO_PIN_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - TYPE_FIELD_NUMBER: builtins.int - gpio_pin: builtins.int - """ - GPIO Pin number (must match Arduino) - """ - name: builtins.str - """ - Name for the GPIO pin (i.e. Front gate, mailbox, etc) - """ - type: global___RemoteHardwarePinType.ValueType - """ - Type of GPIO access available to consumers on the mesh - """ - def __init__( - self, - *, - gpio_pin: builtins.int = ..., - name: builtins.str = ..., - type: global___RemoteHardwarePinType.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["gpio_pin", b"gpio_pin", "name", b"name", "type", b"type"]) -> None: ... - -global___RemoteHardwarePin = RemoteHardwarePin diff --git a/meshtastic/mqtt_pb2.py b/meshtastic/mqtt_pb2.py deleted file mode 100644 index e4ba9e7..0000000 --- a/meshtastic/mqtt_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/mqtt.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from meshtastic import config_pb2 as meshtastic_dot_config__pb2 -from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15meshtastic/mqtt.proto\x12\nmeshtastic\x1a\x17meshtastic/config.proto\x1a\x15meshtastic/mesh.proto\"a\n\x0fServiceEnvelope\x12&\n\x06packet\x18\x01 \x01(\x0b\x32\x16.meshtastic.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\xbc\x03\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12\x32\n\x04role\x18\x03 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12+\n\x08hw_model\x18\x04 \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x38\n\x06region\x18\x06 \x01(\x0e\x32(.meshtastic.Config.LoRaConfig.RegionCode\x12?\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32).meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.mqtt_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _SERVICEENVELOPE._serialized_start=85 - _SERVICEENVELOPE._serialized_end=182 - _MAPREPORT._serialized_start=185 - _MAPREPORT._serialized_end=629 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/mqtt_pb2.pyi b/meshtastic/mqtt_pb2.pyi deleted file mode 100644 index ed2b834..0000000 --- a/meshtastic/mqtt_pb2.pyi +++ /dev/null @@ -1,151 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import meshtastic.config_pb2 -import meshtastic.mesh_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ServiceEnvelope(google.protobuf.message.Message): - """ - This message wraps a MeshPacket with extra metadata about the sender and how it arrived. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PACKET_FIELD_NUMBER: builtins.int - CHANNEL_ID_FIELD_NUMBER: builtins.int - GATEWAY_ID_FIELD_NUMBER: builtins.int - @property - def packet(self) -> meshtastic.mesh_pb2.MeshPacket: - """ - The (probably encrypted) packet - """ - channel_id: builtins.str - """ - The global channel ID it was sent on - """ - gateway_id: builtins.str - """ - The sending gateway node ID. Can we use this to authenticate/prevent fake - nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as - the globally trusted nodenum - """ - def __init__( - self, - *, - packet: meshtastic.mesh_pb2.MeshPacket | None = ..., - channel_id: builtins.str = ..., - gateway_id: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["packet", b"packet"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["channel_id", b"channel_id", "gateway_id", b"gateway_id", "packet", b"packet"]) -> None: ... - -global___ServiceEnvelope = ServiceEnvelope - -@typing_extensions.final -class MapReport(google.protobuf.message.Message): - """ - Information about a node intended to be reported unencrypted to a map using MQTT. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LONG_NAME_FIELD_NUMBER: builtins.int - SHORT_NAME_FIELD_NUMBER: builtins.int - ROLE_FIELD_NUMBER: builtins.int - HW_MODEL_FIELD_NUMBER: builtins.int - FIRMWARE_VERSION_FIELD_NUMBER: builtins.int - REGION_FIELD_NUMBER: builtins.int - MODEM_PRESET_FIELD_NUMBER: builtins.int - HAS_DEFAULT_CHANNEL_FIELD_NUMBER: builtins.int - LATITUDE_I_FIELD_NUMBER: builtins.int - LONGITUDE_I_FIELD_NUMBER: builtins.int - ALTITUDE_FIELD_NUMBER: builtins.int - POSITION_PRECISION_FIELD_NUMBER: builtins.int - NUM_ONLINE_LOCAL_NODES_FIELD_NUMBER: builtins.int - long_name: builtins.str - """ - A full name for this user, i.e. "Kevin Hester" - """ - short_name: builtins.str - """ - A VERY short name, ideally two characters. - Suitable for a tiny OLED screen - """ - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType - """ - Role of the node that applies specific settings for a particular use-case - """ - hw_model: meshtastic.mesh_pb2.HardwareModel.ValueType - """ - Hardware model of the node, i.e. T-Beam, Heltec V3, etc... - """ - firmware_version: builtins.str - """ - Device firmware version string - """ - region: meshtastic.config_pb2.Config.LoRaConfig.RegionCode.ValueType - """ - The region code for the radio (US, CN, EU433, etc...) - """ - modem_preset: meshtastic.config_pb2.Config.LoRaConfig.ModemPreset.ValueType - """ - Modem preset used by the radio (LongFast, MediumSlow, etc...) - """ - has_default_channel: builtins.bool - """ - Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...) - and it uses the default frequency slot given the region and modem preset. - """ - latitude_i: builtins.int - """ - Latitude: multiply by 1e-7 to get degrees in floating point - """ - longitude_i: builtins.int - """ - Longitude: multiply by 1e-7 to get degrees in floating point - """ - altitude: builtins.int - """ - Altitude in meters above MSL - """ - position_precision: builtins.int - """ - Indicates the bits of precision for latitude and longitude set by the sending node - """ - num_online_local_nodes: builtins.int - """ - Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT) - """ - def __init__( - self, - *, - long_name: builtins.str = ..., - short_name: builtins.str = ..., - role: meshtastic.config_pb2.Config.DeviceConfig.Role.ValueType = ..., - hw_model: meshtastic.mesh_pb2.HardwareModel.ValueType = ..., - firmware_version: builtins.str = ..., - region: meshtastic.config_pb2.Config.LoRaConfig.RegionCode.ValueType = ..., - modem_preset: meshtastic.config_pb2.Config.LoRaConfig.ModemPreset.ValueType = ..., - has_default_channel: builtins.bool = ..., - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - altitude: builtins.int = ..., - position_precision: builtins.int = ..., - num_online_local_nodes: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.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 diff --git a/meshtastic/nanopb_pb2.py b/meshtastic/nanopb_pb2.py deleted file mode 100644 index eea6b3e..0000000 --- a/meshtastic/nanopb_pb2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: nanopb.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@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\x0cnanopb.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\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'nanopb_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt) - google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt) - google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt) - google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb) - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\030fi.kapsi.koti.jpa.nanopb' - _FIELDTYPE._serialized_start=985 - _FIELDTYPE._serialized_end=1090 - _INTSIZE._serialized_start=1092 - _INTSIZE._serialized_end=1160 - _TYPENAMEMANGLING._serialized_start=1162 - _TYPENAMEMANGLING._serialized_end=1252 - _DESCRIPTORSIZE._serialized_start=1254 - _DESCRIPTORSIZE._serialized_end=1323 - _NANOPBOPTIONS._serialized_start=51 - _NANOPBOPTIONS._serialized_end=983 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/nanopb_pb2.pyi b/meshtastic/nanopb_pb2.pyi deleted file mode 100644 index 840d1e6..0000000 --- a/meshtastic/nanopb_pb2.pyi +++ /dev/null @@ -1,321 +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_extensions.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.""" - @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. - """ - 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. - """ - 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_extensions.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_extensions.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] diff --git a/meshtastic/paxcount_pb2.py b/meshtastic/paxcount_pb2.py deleted file mode 100644 index 890258f..0000000 --- a/meshtastic/paxcount_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/paxcount.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19meshtastic/paxcount.proto\x12\nmeshtastic\"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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.paxcount_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016PaxcountProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _PAXCOUNT._serialized_start=41 - _PAXCOUNT._serialized_end=94 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/paxcount_pb2.pyi b/meshtastic/paxcount_pb2.pyi deleted file mode 100644 index f4377a1..0000000 --- a/meshtastic/paxcount_pb2.pyi +++ /dev/null @@ -1,49 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class Paxcount(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - WIFI_FIELD_NUMBER: builtins.int - BLE_FIELD_NUMBER: builtins.int - UPTIME_FIELD_NUMBER: builtins.int - wifi: builtins.int - """ - seen Wifi devices - """ - ble: builtins.int - """ - Seen BLE devices - """ - uptime: builtins.int - """ - Uptime in seconds - """ - def __init__( - self, - *, - wifi: builtins.int = ..., - ble: builtins.int = ..., - uptime: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["ble", b"ble", "uptime", b"uptime", "wifi", b"wifi"]) -> None: ... - -global___Paxcount = Paxcount diff --git a/meshtastic/portnums_pb2.py b/meshtastic/portnums_pb2.py deleted file mode 100644 index 77b164a..0000000 --- a/meshtastic/portnums_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/portnums.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19meshtastic/portnums.proto\x12\nmeshtastic*\x8d\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\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\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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.portnums_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _PORTNUM._serialized_start=42 - _PORTNUM._serialized_end=567 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/portnums_pb2.pyi b/meshtastic/portnums_pb2.pyi deleted file mode 100644 index a546cfa..0000000 --- a/meshtastic/portnums_pb2.pyi +++ /dev/null @@ -1,369 +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 sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -class _PortNum: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PortNum.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNKNOWN_APP: _PortNum.ValueType # 0 - """ - Deprecated: do not use in new code (formerly called OPAQUE) - A message sent from a device outside of the mesh, in a form the mesh does not understand - NOTE: This must be 0, because it is documented in IMeshService.aidl to be so - ENCODING: binary undefined - """ - TEXT_MESSAGE_APP: _PortNum.ValueType # 1 - """ - A simple UTF-8 text message, which even the little micros in the mesh - can understand and show on their screen eventually in some circumstances - even signal might send messages in this form (see below) - ENCODING: UTF-8 Plaintext (?) - """ - REMOTE_HARDWARE_APP: _PortNum.ValueType # 2 - """ - Reserved for built-in GPIO/example app. - See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number - ENCODING: Protobuf - """ - POSITION_APP: _PortNum.ValueType # 3 - """ - The built-in position messaging app. - Payload is a Position message. - ENCODING: Protobuf - """ - NODEINFO_APP: _PortNum.ValueType # 4 - """ - The built-in user info app. - Payload is a User message. - ENCODING: Protobuf - """ - ROUTING_APP: _PortNum.ValueType # 5 - """ - Protocol control packets for mesh protocol use. - Payload is a Routing message. - ENCODING: Protobuf - """ - ADMIN_APP: _PortNum.ValueType # 6 - """ - Admin control packets. - Payload is a AdminMessage message. - ENCODING: Protobuf - """ - TEXT_MESSAGE_COMPRESSED_APP: _PortNum.ValueType # 7 - """ - Compressed TEXT_MESSAGE payloads. - ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression - NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed - payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress - any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. - """ - WAYPOINT_APP: _PortNum.ValueType # 8 - """ - Waypoint payloads. - Payload is a Waypoint message. - ENCODING: Protobuf - """ - AUDIO_APP: _PortNum.ValueType # 9 - """ - Audio Payloads. - Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now - ENCODING: codec2 audio frames - NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. - This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. - """ - DETECTION_SENSOR_APP: _PortNum.ValueType # 10 - """ - Same as Text Message but originating from Detection Sensor Module. - NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 - """ - REPLY_APP: _PortNum.ValueType # 32 - """ - Provides a 'ping' service that replies to any packet it receives. - Also serves as a small example module. - ENCODING: ASCII Plaintext - """ - IP_TUNNEL_APP: _PortNum.ValueType # 33 - """ - Used for the python IP tunnel feature - ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. - """ - PAXCOUNTER_APP: _PortNum.ValueType # 34 - """ - Paxcounter lib included in the firmware - ENCODING: protobuf - """ - SERIAL_APP: _PortNum.ValueType # 64 - """ - Provides a hardware serial interface to send and receive from the Meshtastic network. - Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic - network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. - Maximum packet size of 240 bytes. - Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. - ENCODING: binary undefined - """ - STORE_FORWARD_APP: _PortNum.ValueType # 65 - """ - STORE_FORWARD_APP (Work in Progress) - Maintained by Jm Casler (MC Hamster) : jm@casler.org - ENCODING: Protobuf - """ - RANGE_TEST_APP: _PortNum.ValueType # 66 - """ - Optional port for messages for the range test module. - ENCODING: ASCII Plaintext - NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 - """ - TELEMETRY_APP: _PortNum.ValueType # 67 - """ - Provides a format to send and receive telemetry data from the Meshtastic network. - Maintained by Charles Crossan (crossan007) : crossan007@gmail.com - ENCODING: Protobuf - """ - ZPS_APP: _PortNum.ValueType # 68 - """ - Experimental tools for estimating node position without a GPS - Maintained by Github user a-f-G-U-C (a Meshtastic contributor) - Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS - ENCODING: arrays of int64 fields - """ - SIMULATOR_APP: _PortNum.ValueType # 69 - """ - Used to let multiple instances of Linux native applications communicate - as if they did using their LoRa chip. - Maintained by GitHub user GUVWAF. - Project files at https://github.com/GUVWAF/Meshtasticator - ENCODING: Protobuf (?) - """ - TRACEROUTE_APP: _PortNum.ValueType # 70 - """ - Provides a traceroute functionality to show the route a packet towards - a certain destination would take on the mesh. - ENCODING: Protobuf - """ - NEIGHBORINFO_APP: _PortNum.ValueType # 71 - """ - Aggregates edge info for the network by sending out a list of each node's neighbors - ENCODING: Protobuf - """ - ATAK_PLUGIN: _PortNum.ValueType # 72 - """ - ATAK Plugin - Portnum for payloads from the official Meshtastic ATAK plugin - """ - MAP_REPORT_APP: _PortNum.ValueType # 73 - """ - Provides unencrypted information about a node for consumption by a map via MQTT - """ - PRIVATE_APP: _PortNum.ValueType # 256 - """ - Private applications should use portnums >= 256. - To simplify initial development and testing you can use "PRIVATE_APP" - in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) - """ - ATAK_FORWARDER: _PortNum.ValueType # 257 - """ - ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder - ENCODING: libcotshrink - """ - MAX: _PortNum.ValueType # 511 - """ - Currently we limit port nums to no higher than this value - """ - -class PortNum(_PortNum, metaclass=_PortNumEnumTypeWrapper): - """ - For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a - unique 'portnum' for their application. - If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this - master table. - PortNums should be assigned in the following range: - 0-63 Core Meshtastic use, do not use for third party apps - 64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application - 256-511 Use one of these portnums for your private applications that you don't want to register publically - All other values are reserved. - Note: This was formerly a Type enum named 'typ' with the same id # - We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. - This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. - """ - -UNKNOWN_APP: PortNum.ValueType # 0 -""" -Deprecated: do not use in new code (formerly called OPAQUE) -A message sent from a device outside of the mesh, in a form the mesh does not understand -NOTE: This must be 0, because it is documented in IMeshService.aidl to be so -ENCODING: binary undefined -""" -TEXT_MESSAGE_APP: PortNum.ValueType # 1 -""" -A simple UTF-8 text message, which even the little micros in the mesh -can understand and show on their screen eventually in some circumstances -even signal might send messages in this form (see below) -ENCODING: UTF-8 Plaintext (?) -""" -REMOTE_HARDWARE_APP: PortNum.ValueType # 2 -""" -Reserved for built-in GPIO/example app. -See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number -ENCODING: Protobuf -""" -POSITION_APP: PortNum.ValueType # 3 -""" -The built-in position messaging app. -Payload is a Position message. -ENCODING: Protobuf -""" -NODEINFO_APP: PortNum.ValueType # 4 -""" -The built-in user info app. -Payload is a User message. -ENCODING: Protobuf -""" -ROUTING_APP: PortNum.ValueType # 5 -""" -Protocol control packets for mesh protocol use. -Payload is a Routing message. -ENCODING: Protobuf -""" -ADMIN_APP: PortNum.ValueType # 6 -""" -Admin control packets. -Payload is a AdminMessage message. -ENCODING: Protobuf -""" -TEXT_MESSAGE_COMPRESSED_APP: PortNum.ValueType # 7 -""" -Compressed TEXT_MESSAGE payloads. -ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression -NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed -payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress -any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. -""" -WAYPOINT_APP: PortNum.ValueType # 8 -""" -Waypoint payloads. -Payload is a Waypoint message. -ENCODING: Protobuf -""" -AUDIO_APP: PortNum.ValueType # 9 -""" -Audio Payloads. -Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now -ENCODING: codec2 audio frames -NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. -This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. -""" -DETECTION_SENSOR_APP: PortNum.ValueType # 10 -""" -Same as Text Message but originating from Detection Sensor Module. -NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 -""" -REPLY_APP: PortNum.ValueType # 32 -""" -Provides a 'ping' service that replies to any packet it receives. -Also serves as a small example module. -ENCODING: ASCII Plaintext -""" -IP_TUNNEL_APP: PortNum.ValueType # 33 -""" -Used for the python IP tunnel feature -ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. -""" -PAXCOUNTER_APP: PortNum.ValueType # 34 -""" -Paxcounter lib included in the firmware -ENCODING: protobuf -""" -SERIAL_APP: PortNum.ValueType # 64 -""" -Provides a hardware serial interface to send and receive from the Meshtastic network. -Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic -network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. -Maximum packet size of 240 bytes. -Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. -ENCODING: binary undefined -""" -STORE_FORWARD_APP: PortNum.ValueType # 65 -""" -STORE_FORWARD_APP (Work in Progress) -Maintained by Jm Casler (MC Hamster) : jm@casler.org -ENCODING: Protobuf -""" -RANGE_TEST_APP: PortNum.ValueType # 66 -""" -Optional port for messages for the range test module. -ENCODING: ASCII Plaintext -NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 -""" -TELEMETRY_APP: PortNum.ValueType # 67 -""" -Provides a format to send and receive telemetry data from the Meshtastic network. -Maintained by Charles Crossan (crossan007) : crossan007@gmail.com -ENCODING: Protobuf -""" -ZPS_APP: PortNum.ValueType # 68 -""" -Experimental tools for estimating node position without a GPS -Maintained by Github user a-f-G-U-C (a Meshtastic contributor) -Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS -ENCODING: arrays of int64 fields -""" -SIMULATOR_APP: PortNum.ValueType # 69 -""" -Used to let multiple instances of Linux native applications communicate -as if they did using their LoRa chip. -Maintained by GitHub user GUVWAF. -Project files at https://github.com/GUVWAF/Meshtasticator -ENCODING: Protobuf (?) -""" -TRACEROUTE_APP: PortNum.ValueType # 70 -""" -Provides a traceroute functionality to show the route a packet towards -a certain destination would take on the mesh. -ENCODING: Protobuf -""" -NEIGHBORINFO_APP: PortNum.ValueType # 71 -""" -Aggregates edge info for the network by sending out a list of each node's neighbors -ENCODING: Protobuf -""" -ATAK_PLUGIN: PortNum.ValueType # 72 -""" -ATAK Plugin -Portnum for payloads from the official Meshtastic ATAK plugin -""" -MAP_REPORT_APP: PortNum.ValueType # 73 -""" -Provides unencrypted information about a node for consumption by a map via MQTT -""" -PRIVATE_APP: PortNum.ValueType # 256 -""" -Private applications should use portnums >= 256. -To simplify initial development and testing you can use "PRIVATE_APP" -in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) -""" -ATAK_FORWARDER: PortNum.ValueType # 257 -""" -ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder -ENCODING: libcotshrink -""" -MAX: PortNum.ValueType # 511 -""" -Currently we limit port nums to no higher than this value -""" -global___PortNum = PortNum diff --git a/meshtastic/remote_hardware_pb2.py b/meshtastic/remote_hardware_pb2.py deleted file mode 100644 index c1365ff..0000000 --- a/meshtastic/remote_hardware_pb2.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/remote_hardware.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/remote_hardware.proto\x12\nmeshtastic\"\xd6\x01\n\x0fHardwareMessage\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.remote_hardware_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _HARDWAREMESSAGE._serialized_start=49 - _HARDWAREMESSAGE._serialized_end=263 - _HARDWAREMESSAGE_TYPE._serialized_start=155 - _HARDWAREMESSAGE_TYPE._serialized_end=263 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/remote_hardware_pb2.pyi b/meshtastic/remote_hardware_pb2.pyi deleted file mode 100644 index ff4fd83..0000000 --- a/meshtastic/remote_hardware_pb2.pyi +++ /dev/null @@ -1,125 +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 - -@typing_extensions.final -class HardwareMessage(google.protobuf.message.Message): - """ - An example app to show off the module system. This message is used for - REMOTE_HARDWARE_APP PortNums. - Also provides easy remote access to any GPIO. - In the future other remote hardware operations can be added based on user interest - (i.e. serial output, spi/i2c input/output). - FIXME - currently this feature is turned on by default which is dangerous - because no security yet (beyond the channel mechanism). - It should be off by default and then protected based on some TBD mechanism - (a special channel once multichannel support is included?) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Type: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[HardwareMessage._Type.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: HardwareMessage._Type.ValueType # 0 - """ - Unset/unused - """ - WRITE_GPIOS: HardwareMessage._Type.ValueType # 1 - """ - Set gpio gpios based on gpio_mask/gpio_value - """ - WATCH_GPIOS: HardwareMessage._Type.ValueType # 2 - """ - We are now interested in watching the gpio_mask gpios. - If the selected gpios change, please broadcast GPIOS_CHANGED. - Will implicitly change the gpios requested to be INPUT gpios. - """ - GPIOS_CHANGED: HardwareMessage._Type.ValueType # 3 - """ - The gpios listed in gpio_mask have changed, the new values are listed in gpio_value - """ - READ_GPIOS: HardwareMessage._Type.ValueType # 4 - """ - Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated - """ - READ_GPIOS_REPLY: HardwareMessage._Type.ValueType # 5 - """ - A reply to READ_GPIOS. gpio_mask and gpio_value will be populated - """ - - class Type(_Type, metaclass=_TypeEnumTypeWrapper): - """ - TODO: REPLACE - """ - - UNSET: HardwareMessage.Type.ValueType # 0 - """ - Unset/unused - """ - WRITE_GPIOS: HardwareMessage.Type.ValueType # 1 - """ - Set gpio gpios based on gpio_mask/gpio_value - """ - WATCH_GPIOS: HardwareMessage.Type.ValueType # 2 - """ - We are now interested in watching the gpio_mask gpios. - If the selected gpios change, please broadcast GPIOS_CHANGED. - Will implicitly change the gpios requested to be INPUT gpios. - """ - GPIOS_CHANGED: HardwareMessage.Type.ValueType # 3 - """ - The gpios listed in gpio_mask have changed, the new values are listed in gpio_value - """ - READ_GPIOS: HardwareMessage.Type.ValueType # 4 - """ - Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated - """ - READ_GPIOS_REPLY: HardwareMessage.Type.ValueType # 5 - """ - A reply to READ_GPIOS. gpio_mask and gpio_value will be populated - """ - - TYPE_FIELD_NUMBER: builtins.int - GPIO_MASK_FIELD_NUMBER: builtins.int - GPIO_VALUE_FIELD_NUMBER: builtins.int - type: global___HardwareMessage.Type.ValueType - """ - What type of HardwareMessage is this? - """ - gpio_mask: builtins.int - """ - What gpios are we changing. Not used for all MessageTypes, see MessageType for details - """ - gpio_value: builtins.int - """ - For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios. - Not used for all MessageTypes, see MessageType for details - """ - def __init__( - self, - *, - type: global___HardwareMessage.Type.ValueType = ..., - gpio_mask: builtins.int = ..., - gpio_value: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["gpio_mask", b"gpio_mask", "gpio_value", b"gpio_value", "type", b"type"]) -> None: ... - -global___HardwareMessage = HardwareMessage diff --git a/meshtastic/rtttl_pb2.py b/meshtastic/rtttl_pb2.py deleted file mode 100644 index a69b868..0000000 --- a/meshtastic/rtttl_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/rtttl.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/rtttl.proto\x12\nmeshtastic\"\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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.rtttl_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _RTTTLCONFIG._serialized_start=38 - _RTTTLCONFIG._serialized_end=69 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/rtttl_pb2.pyi b/meshtastic/rtttl_pb2.pyi deleted file mode 100644 index ddf8591..0000000 --- a/meshtastic/rtttl_pb2.pyi +++ /dev/null @@ -1,37 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import google.protobuf.descriptor -import google.protobuf.message -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class RTTTLConfig(google.protobuf.message.Message): - """ - Canned message module configuration. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RINGTONE_FIELD_NUMBER: builtins.int - ringtone: builtins.str - """ - Ringtone for PWM Buzzer in RTTTL Format. - """ - def __init__( - self, - *, - ringtone: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["ringtone", b"ringtone"]) -> None: ... - -global___RTTTLConfig = RTTTLConfig diff --git a/meshtastic/storeforward_pb2.py b/meshtastic/storeforward_pb2.py deleted file mode 100644 index b81fd73..0000000 --- a/meshtastic/storeforward_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/storeforward.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dmeshtastic/storeforward.proto\x12\nmeshtastic\"\x9c\x07\n\x0fStoreAndForward\x12\x37\n\x02rr\x18\x01 \x01(\x0e\x32+.meshtastic.StoreAndForward.RequestResponse\x12\x37\n\x05stats\x18\x02 \x01(\x0b\x32&.meshtastic.StoreAndForward.StatisticsH\x00\x12\x36\n\x07history\x18\x03 \x01(\x0b\x32#.meshtastic.StoreAndForward.HistoryH\x00\x12:\n\theartbeat\x18\x04 \x01(\x0b\x32%.meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.storeforward_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _STOREANDFORWARD._serialized_start=46 - _STOREANDFORWARD._serialized_end=970 - _STOREANDFORWARD_STATISTICS._serialized_start=312 - _STOREANDFORWARD_STATISTICS._serialized_end=517 - _STOREANDFORWARD_HISTORY._serialized_start=519 - _STOREANDFORWARD_HISTORY._serialized_end=592 - _STOREANDFORWARD_HEARTBEAT._serialized_start=594 - _STOREANDFORWARD_HEARTBEAT._serialized_end=640 - _STOREANDFORWARD_REQUESTRESPONSE._serialized_start=643 - _STOREANDFORWARD_REQUESTRESPONSE._serialized_end=959 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/storeforward_pb2.pyi b/meshtastic/storeforward_pb2.pyi deleted file mode 100644 index cd2d751..0000000 --- a/meshtastic/storeforward_pb2.pyi +++ /dev/null @@ -1,341 +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 - -@typing_extensions.final -class StoreAndForward(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _RequestResponse: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _RequestResponseEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StoreAndForward._RequestResponse.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - UNSET: StoreAndForward._RequestResponse.ValueType # 0 - """ - Unset/unused - """ - ROUTER_ERROR: StoreAndForward._RequestResponse.ValueType # 1 - """ - Router is an in error state. - """ - ROUTER_HEARTBEAT: StoreAndForward._RequestResponse.ValueType # 2 - """ - Router heartbeat - """ - ROUTER_PING: StoreAndForward._RequestResponse.ValueType # 3 - """ - Router has requested the client respond. This can work as a - "are you there" message. - """ - ROUTER_PONG: StoreAndForward._RequestResponse.ValueType # 4 - """ - The response to a "Ping" - """ - ROUTER_BUSY: StoreAndForward._RequestResponse.ValueType # 5 - """ - Router is currently busy. Please try again later. - """ - ROUTER_HISTORY: StoreAndForward._RequestResponse.ValueType # 6 - """ - Router is responding to a request for history. - """ - ROUTER_STATS: StoreAndForward._RequestResponse.ValueType # 7 - """ - Router is responding to a request for stats. - """ - ROUTER_TEXT_DIRECT: StoreAndForward._RequestResponse.ValueType # 8 - """ - Router sends a text message from its history that was a direct message. - """ - ROUTER_TEXT_BROADCAST: StoreAndForward._RequestResponse.ValueType # 9 - """ - Router sends a text message from its history that was a broadcast. - """ - CLIENT_ERROR: StoreAndForward._RequestResponse.ValueType # 64 - """ - Client is an in error state. - """ - CLIENT_HISTORY: StoreAndForward._RequestResponse.ValueType # 65 - """ - Client has requested a replay from the router. - """ - CLIENT_STATS: StoreAndForward._RequestResponse.ValueType # 66 - """ - Client has requested stats from the router. - """ - CLIENT_PING: StoreAndForward._RequestResponse.ValueType # 67 - """ - Client has requested the router respond. This can work as a - "are you there" message. - """ - CLIENT_PONG: StoreAndForward._RequestResponse.ValueType # 68 - """ - The response to a "Ping" - """ - CLIENT_ABORT: StoreAndForward._RequestResponse.ValueType # 106 - """ - Client has requested that the router abort processing the client's request - """ - - class RequestResponse(_RequestResponse, metaclass=_RequestResponseEnumTypeWrapper): - """ - 001 - 063 = From Router - 064 - 127 = From Client - """ - - UNSET: StoreAndForward.RequestResponse.ValueType # 0 - """ - Unset/unused - """ - ROUTER_ERROR: StoreAndForward.RequestResponse.ValueType # 1 - """ - Router is an in error state. - """ - ROUTER_HEARTBEAT: StoreAndForward.RequestResponse.ValueType # 2 - """ - Router heartbeat - """ - ROUTER_PING: StoreAndForward.RequestResponse.ValueType # 3 - """ - Router has requested the client respond. This can work as a - "are you there" message. - """ - ROUTER_PONG: StoreAndForward.RequestResponse.ValueType # 4 - """ - The response to a "Ping" - """ - ROUTER_BUSY: StoreAndForward.RequestResponse.ValueType # 5 - """ - Router is currently busy. Please try again later. - """ - ROUTER_HISTORY: StoreAndForward.RequestResponse.ValueType # 6 - """ - Router is responding to a request for history. - """ - ROUTER_STATS: StoreAndForward.RequestResponse.ValueType # 7 - """ - Router is responding to a request for stats. - """ - ROUTER_TEXT_DIRECT: StoreAndForward.RequestResponse.ValueType # 8 - """ - Router sends a text message from its history that was a direct message. - """ - ROUTER_TEXT_BROADCAST: StoreAndForward.RequestResponse.ValueType # 9 - """ - Router sends a text message from its history that was a broadcast. - """ - CLIENT_ERROR: StoreAndForward.RequestResponse.ValueType # 64 - """ - Client is an in error state. - """ - CLIENT_HISTORY: StoreAndForward.RequestResponse.ValueType # 65 - """ - Client has requested a replay from the router. - """ - CLIENT_STATS: StoreAndForward.RequestResponse.ValueType # 66 - """ - Client has requested stats from the router. - """ - CLIENT_PING: StoreAndForward.RequestResponse.ValueType # 67 - """ - Client has requested the router respond. This can work as a - "are you there" message. - """ - CLIENT_PONG: StoreAndForward.RequestResponse.ValueType # 68 - """ - The response to a "Ping" - """ - CLIENT_ABORT: StoreAndForward.RequestResponse.ValueType # 106 - """ - Client has requested that the router abort processing the client's request - """ - - @typing_extensions.final - class Statistics(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MESSAGES_TOTAL_FIELD_NUMBER: builtins.int - MESSAGES_SAVED_FIELD_NUMBER: builtins.int - MESSAGES_MAX_FIELD_NUMBER: builtins.int - UP_TIME_FIELD_NUMBER: builtins.int - REQUESTS_FIELD_NUMBER: builtins.int - REQUESTS_HISTORY_FIELD_NUMBER: builtins.int - HEARTBEAT_FIELD_NUMBER: builtins.int - RETURN_MAX_FIELD_NUMBER: builtins.int - RETURN_WINDOW_FIELD_NUMBER: builtins.int - messages_total: builtins.int - """ - Number of messages we have ever seen - """ - messages_saved: builtins.int - """ - Number of messages we have currently saved our history. - """ - messages_max: builtins.int - """ - Maximum number of messages we will save - """ - up_time: builtins.int - """ - Router uptime in seconds - """ - requests: builtins.int - """ - Number of times any client sent a request to the S&F. - """ - requests_history: builtins.int - """ - Number of times the history was requested. - """ - heartbeat: builtins.bool - """ - Is the heartbeat enabled on the server? - """ - return_max: builtins.int - """ - Maximum number of messages the server will return. - """ - return_window: builtins.int - """ - Maximum history window in minutes the server will return messages from. - """ - def __init__( - self, - *, - messages_total: builtins.int = ..., - messages_saved: builtins.int = ..., - messages_max: builtins.int = ..., - up_time: builtins.int = ..., - requests: builtins.int = ..., - requests_history: builtins.int = ..., - heartbeat: builtins.bool = ..., - return_max: builtins.int = ..., - return_window: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["heartbeat", b"heartbeat", "messages_max", b"messages_max", "messages_saved", b"messages_saved", "messages_total", b"messages_total", "requests", b"requests", "requests_history", b"requests_history", "return_max", b"return_max", "return_window", b"return_window", "up_time", b"up_time"]) -> None: ... - - @typing_extensions.final - class History(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - HISTORY_MESSAGES_FIELD_NUMBER: builtins.int - WINDOW_FIELD_NUMBER: builtins.int - LAST_REQUEST_FIELD_NUMBER: builtins.int - history_messages: builtins.int - """ - Number of that will be sent to the client - """ - window: builtins.int - """ - The window of messages that was used to filter the history client requested - """ - last_request: builtins.int - """ - Index in the packet history of the last message sent in a previous request to the server. - Will be sent to the client before sending the history and can be set in a subsequent request to avoid getting packets the server already sent to the client. - """ - def __init__( - self, - *, - history_messages: builtins.int = ..., - window: builtins.int = ..., - last_request: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["history_messages", b"history_messages", "last_request", b"last_request", "window", b"window"]) -> None: ... - - @typing_extensions.final - class Heartbeat(google.protobuf.message.Message): - """ - TODO: REPLACE - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PERIOD_FIELD_NUMBER: builtins.int - SECONDARY_FIELD_NUMBER: builtins.int - period: builtins.int - """ - Period in seconds that the heartbeat is sent out that will be sent to the client - """ - secondary: builtins.int - """ - If set, this is not the primary Store & Forward router on the mesh - """ - def __init__( - self, - *, - period: builtins.int = ..., - secondary: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["period", b"period", "secondary", b"secondary"]) -> None: ... - - RR_FIELD_NUMBER: builtins.int - STATS_FIELD_NUMBER: builtins.int - HISTORY_FIELD_NUMBER: builtins.int - HEARTBEAT_FIELD_NUMBER: builtins.int - TEXT_FIELD_NUMBER: builtins.int - rr: global___StoreAndForward.RequestResponse.ValueType - """ - TODO: REPLACE - """ - @property - def stats(self) -> global___StoreAndForward.Statistics: - """ - TODO: REPLACE - """ - @property - def history(self) -> global___StoreAndForward.History: - """ - TODO: REPLACE - """ - @property - def heartbeat(self) -> global___StoreAndForward.Heartbeat: - """ - TODO: REPLACE - """ - text: builtins.bytes - """ - Text from history message. - """ - def __init__( - self, - *, - rr: global___StoreAndForward.RequestResponse.ValueType = ..., - stats: global___StoreAndForward.Statistics | None = ..., - history: global___StoreAndForward.History | None = ..., - heartbeat: global___StoreAndForward.Heartbeat | None = ..., - text: builtins.bytes = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["heartbeat", b"heartbeat", "history", b"history", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["heartbeat", b"heartbeat", "history", b"history", "rr", b"rr", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["variant", b"variant"]) -> typing_extensions.Literal["stats", "history", "heartbeat", "text"] | None: ... - -global___StoreAndForward = StoreAndForward diff --git a/meshtastic/telemetry_pb2.py b/meshtastic/telemetry_pb2.py deleted file mode 100644 index b3c16e8..0000000 --- a/meshtastic/telemetry_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/telemetry.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ameshtastic/telemetry.proto\x12\nmeshtastic\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xa6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\x89\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12\x33\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x19.meshtastic.DeviceMetricsH\x00\x12=\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x1e.meshtastic.EnvironmentMetricsH\x00\x12<\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32\x1d.meshtastic.AirQualityMetricsH\x00\x12\x31\n\rpower_metrics\x18\x05 \x01(\x0b\x32\x18.meshtastic.PowerMetricsH\x00\x42\t\n\x07variant*\xdd\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.telemetry_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _TELEMETRYSENSORTYPE._serialized_start=1205 - _TELEMETRYSENSORTYPE._serialized_end=1554 - _DEVICEMETRICS._serialized_start=43 - _DEVICEMETRICS._serialized_end=172 - _ENVIRONMENTMETRICS._serialized_start=175 - _ENVIRONMENTMETRICS._serialized_end=469 - _POWERMETRICS._serialized_start=472 - _POWERMETRICS._serialized_end=612 - _AIRQUALITYMETRICS._serialized_start=615 - _AIRQUALITYMETRICS._serialized_end=934 - _TELEMETRY._serialized_start=937 - _TELEMETRY._serialized_end=1202 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/telemetry_pb2.pyi b/meshtastic/telemetry_pb2.pyi deleted file mode 100644 index 552d51b..0000000 --- a/meshtastic/telemetry_pb2.pyi +++ /dev/null @@ -1,571 +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 _TelemetrySensorType: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TelemetrySensorType.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - SENSOR_UNSET: _TelemetrySensorType.ValueType # 0 - """ - No external telemetry sensor explicitly set - """ - BME280: _TelemetrySensorType.ValueType # 1 - """ - High accuracy temperature, pressure, humidity - """ - BME680: _TelemetrySensorType.ValueType # 2 - """ - High accuracy temperature, pressure, humidity, and air resistance - """ - MCP9808: _TelemetrySensorType.ValueType # 3 - """ - Very high accuracy temperature - """ - INA260: _TelemetrySensorType.ValueType # 4 - """ - Moderate accuracy current and voltage - """ - INA219: _TelemetrySensorType.ValueType # 5 - """ - Moderate accuracy current and voltage - """ - BMP280: _TelemetrySensorType.ValueType # 6 - """ - High accuracy temperature and pressure - """ - SHTC3: _TelemetrySensorType.ValueType # 7 - """ - High accuracy temperature and humidity - """ - LPS22: _TelemetrySensorType.ValueType # 8 - """ - High accuracy pressure - """ - QMC6310: _TelemetrySensorType.ValueType # 9 - """ - 3-Axis magnetic sensor - """ - QMI8658: _TelemetrySensorType.ValueType # 10 - """ - 6-Axis inertial measurement sensor - """ - QMC5883L: _TelemetrySensorType.ValueType # 11 - """ - 3-Axis magnetic sensor - """ - SHT31: _TelemetrySensorType.ValueType # 12 - """ - High accuracy temperature and humidity - """ - PMSA003I: _TelemetrySensorType.ValueType # 13 - """ - PM2.5 air quality sensor - """ - INA3221: _TelemetrySensorType.ValueType # 14 - """ - INA3221 3 Channel Voltage / Current Sensor - """ - BMP085: _TelemetrySensorType.ValueType # 15 - """ - BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) - """ - RCWL9620: _TelemetrySensorType.ValueType # 16 - """ - RCWL-9620 Doppler Radar Distance Sensor, used for water level detection - """ - SHT4X: _TelemetrySensorType.ValueType # 17 - """ - Sensirion High accuracy temperature and humidity - """ - VEML7700: _TelemetrySensorType.ValueType # 18 - """ - VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. - """ - MLX90632: _TelemetrySensorType.ValueType # 19 - """ - MLX90632 non-contact IR temperature sensor. - """ - OPT3001: _TelemetrySensorType.ValueType # 20 - """ - TI OPT3001 Ambient Light Sensor - """ - LTR390UV: _TelemetrySensorType.ValueType # 21 - """ - Lite On LTR-390UV-01 UV Light Sensor - """ - TSL25911FN: _TelemetrySensorType.ValueType # 22 - """ - AMS TSL25911FN RGB Light Sensor - """ - AHT10: _TelemetrySensorType.ValueType # 23 - """ - AHT10 Integrated temperature and humidity sensor - """ - DFROBOT_LARK: _TelemetrySensorType.ValueType # 24 - """ - DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) - """ - -class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): - """ - Supported I2C Sensors for telemetry in Meshtastic - """ - -SENSOR_UNSET: TelemetrySensorType.ValueType # 0 -""" -No external telemetry sensor explicitly set -""" -BME280: TelemetrySensorType.ValueType # 1 -""" -High accuracy temperature, pressure, humidity -""" -BME680: TelemetrySensorType.ValueType # 2 -""" -High accuracy temperature, pressure, humidity, and air resistance -""" -MCP9808: TelemetrySensorType.ValueType # 3 -""" -Very high accuracy temperature -""" -INA260: TelemetrySensorType.ValueType # 4 -""" -Moderate accuracy current and voltage -""" -INA219: TelemetrySensorType.ValueType # 5 -""" -Moderate accuracy current and voltage -""" -BMP280: TelemetrySensorType.ValueType # 6 -""" -High accuracy temperature and pressure -""" -SHTC3: TelemetrySensorType.ValueType # 7 -""" -High accuracy temperature and humidity -""" -LPS22: TelemetrySensorType.ValueType # 8 -""" -High accuracy pressure -""" -QMC6310: TelemetrySensorType.ValueType # 9 -""" -3-Axis magnetic sensor -""" -QMI8658: TelemetrySensorType.ValueType # 10 -""" -6-Axis inertial measurement sensor -""" -QMC5883L: TelemetrySensorType.ValueType # 11 -""" -3-Axis magnetic sensor -""" -SHT31: TelemetrySensorType.ValueType # 12 -""" -High accuracy temperature and humidity -""" -PMSA003I: TelemetrySensorType.ValueType # 13 -""" -PM2.5 air quality sensor -""" -INA3221: TelemetrySensorType.ValueType # 14 -""" -INA3221 3 Channel Voltage / Current Sensor -""" -BMP085: TelemetrySensorType.ValueType # 15 -""" -BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) -""" -RCWL9620: TelemetrySensorType.ValueType # 16 -""" -RCWL-9620 Doppler Radar Distance Sensor, used for water level detection -""" -SHT4X: TelemetrySensorType.ValueType # 17 -""" -Sensirion High accuracy temperature and humidity -""" -VEML7700: TelemetrySensorType.ValueType # 18 -""" -VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. -""" -MLX90632: TelemetrySensorType.ValueType # 19 -""" -MLX90632 non-contact IR temperature sensor. -""" -OPT3001: TelemetrySensorType.ValueType # 20 -""" -TI OPT3001 Ambient Light Sensor -""" -LTR390UV: TelemetrySensorType.ValueType # 21 -""" -Lite On LTR-390UV-01 UV Light Sensor -""" -TSL25911FN: TelemetrySensorType.ValueType # 22 -""" -AMS TSL25911FN RGB Light Sensor -""" -AHT10: TelemetrySensorType.ValueType # 23 -""" -AHT10 Integrated temperature and humidity sensor -""" -DFROBOT_LARK: TelemetrySensorType.ValueType # 24 -""" -DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) -""" -global___TelemetrySensorType = TelemetrySensorType - -@typing_extensions.final -class DeviceMetrics(google.protobuf.message.Message): - """ - Key native device metrics such as battery level - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - BATTERY_LEVEL_FIELD_NUMBER: builtins.int - VOLTAGE_FIELD_NUMBER: builtins.int - CHANNEL_UTILIZATION_FIELD_NUMBER: builtins.int - AIR_UTIL_TX_FIELD_NUMBER: builtins.int - UPTIME_SECONDS_FIELD_NUMBER: builtins.int - battery_level: builtins.int - """ - 0-100 (>100 means powered) - """ - voltage: builtins.float - """ - Voltage measured - """ - channel_utilization: builtins.float - """ - Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). - """ - air_util_tx: builtins.float - """ - Percent of airtime for transmission used within the last hour. - """ - uptime_seconds: builtins.int - """ - How long the device has been running since the last reboot (in seconds) - """ - def __init__( - self, - *, - battery_level: builtins.int = ..., - voltage: builtins.float = ..., - channel_utilization: builtins.float = ..., - air_util_tx: builtins.float = ..., - uptime_seconds: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["air_util_tx", b"air_util_tx", "battery_level", b"battery_level", "channel_utilization", b"channel_utilization", "uptime_seconds", b"uptime_seconds", "voltage", b"voltage"]) -> None: ... - -global___DeviceMetrics = DeviceMetrics - -@typing_extensions.final -class EnvironmentMetrics(google.protobuf.message.Message): - """ - Weather station or other environmental metrics - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TEMPERATURE_FIELD_NUMBER: builtins.int - RELATIVE_HUMIDITY_FIELD_NUMBER: builtins.int - BAROMETRIC_PRESSURE_FIELD_NUMBER: builtins.int - GAS_RESISTANCE_FIELD_NUMBER: builtins.int - VOLTAGE_FIELD_NUMBER: builtins.int - CURRENT_FIELD_NUMBER: builtins.int - IAQ_FIELD_NUMBER: builtins.int - DISTANCE_FIELD_NUMBER: builtins.int - LUX_FIELD_NUMBER: builtins.int - WHITE_LUX_FIELD_NUMBER: builtins.int - IR_LUX_FIELD_NUMBER: builtins.int - UV_LUX_FIELD_NUMBER: builtins.int - WIND_DIRECTION_FIELD_NUMBER: builtins.int - WIND_SPEED_FIELD_NUMBER: builtins.int - temperature: builtins.float - """ - Temperature measured - """ - relative_humidity: builtins.float - """ - Relative humidity percent measured - """ - barometric_pressure: builtins.float - """ - Barometric pressure in hPA measured - """ - gas_resistance: builtins.float - """ - Gas resistance in MOhm measured - """ - voltage: builtins.float - """ - Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) - """ - current: builtins.float - """ - Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) - """ - iaq: builtins.int - """ - relative scale IAQ value as measured by Bosch BME680 . value 0-500. - Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. - """ - distance: builtins.float - """ - RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm. - """ - lux: builtins.float - """ - VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. - """ - white_lux: builtins.float - """ - VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor. - """ - ir_lux: builtins.float - """ - Infrared lux - """ - uv_lux: builtins.float - """ - Ultraviolet lux - """ - wind_direction: builtins.int - """ - Wind direction in degrees - 0 degrees = North, 90 = East, etc... - """ - wind_speed: builtins.float - """ - Wind speed in m/s - """ - def __init__( - self, - *, - temperature: builtins.float = ..., - relative_humidity: builtins.float = ..., - barometric_pressure: builtins.float = ..., - gas_resistance: builtins.float = ..., - voltage: builtins.float = ..., - current: builtins.float = ..., - iaq: builtins.int = ..., - distance: builtins.float = ..., - lux: builtins.float = ..., - white_lux: builtins.float = ..., - ir_lux: builtins.float = ..., - uv_lux: builtins.float = ..., - wind_direction: builtins.int = ..., - wind_speed: builtins.float = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.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", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_speed", b"wind_speed"]) -> None: ... - -global___EnvironmentMetrics = EnvironmentMetrics - -@typing_extensions.final -class PowerMetrics(google.protobuf.message.Message): - """ - Power Metrics (voltage / current / etc) - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CH1_VOLTAGE_FIELD_NUMBER: builtins.int - CH1_CURRENT_FIELD_NUMBER: builtins.int - CH2_VOLTAGE_FIELD_NUMBER: builtins.int - CH2_CURRENT_FIELD_NUMBER: builtins.int - CH3_VOLTAGE_FIELD_NUMBER: builtins.int - CH3_CURRENT_FIELD_NUMBER: builtins.int - ch1_voltage: builtins.float - """ - Voltage (Ch1) - """ - ch1_current: builtins.float - """ - Current (Ch1) - """ - ch2_voltage: builtins.float - """ - Voltage (Ch2) - """ - ch2_current: builtins.float - """ - Current (Ch2) - """ - ch3_voltage: builtins.float - """ - Voltage (Ch3) - """ - ch3_current: builtins.float - """ - Current (Ch3) - """ - def __init__( - self, - *, - ch1_voltage: builtins.float = ..., - ch1_current: builtins.float = ..., - ch2_voltage: builtins.float = ..., - ch2_current: builtins.float = ..., - ch3_voltage: builtins.float = ..., - ch3_current: builtins.float = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.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"]) -> None: ... - -global___PowerMetrics = PowerMetrics - -@typing_extensions.final -class AirQualityMetrics(google.protobuf.message.Message): - """ - Air quality metrics - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PM10_STANDARD_FIELD_NUMBER: builtins.int - PM25_STANDARD_FIELD_NUMBER: builtins.int - PM100_STANDARD_FIELD_NUMBER: builtins.int - PM10_ENVIRONMENTAL_FIELD_NUMBER: builtins.int - PM25_ENVIRONMENTAL_FIELD_NUMBER: builtins.int - PM100_ENVIRONMENTAL_FIELD_NUMBER: builtins.int - PARTICLES_03UM_FIELD_NUMBER: builtins.int - PARTICLES_05UM_FIELD_NUMBER: builtins.int - PARTICLES_10UM_FIELD_NUMBER: builtins.int - PARTICLES_25UM_FIELD_NUMBER: builtins.int - PARTICLES_50UM_FIELD_NUMBER: builtins.int - PARTICLES_100UM_FIELD_NUMBER: builtins.int - pm10_standard: builtins.int - """ - Concentration Units Standard PM1.0 - """ - pm25_standard: builtins.int - """ - Concentration Units Standard PM2.5 - """ - pm100_standard: builtins.int - """ - Concentration Units Standard PM10.0 - """ - pm10_environmental: builtins.int - """ - Concentration Units Environmental PM1.0 - """ - pm25_environmental: builtins.int - """ - Concentration Units Environmental PM2.5 - """ - pm100_environmental: builtins.int - """ - Concentration Units Environmental PM10.0 - """ - particles_03um: builtins.int - """ - 0.3um Particle Count - """ - particles_05um: builtins.int - """ - 0.5um Particle Count - """ - particles_10um: builtins.int - """ - 1.0um Particle Count - """ - particles_25um: builtins.int - """ - 2.5um Particle Count - """ - particles_50um: builtins.int - """ - 5.0um Particle Count - """ - particles_100um: builtins.int - """ - 10.0um Particle Count - """ - def __init__( - self, - *, - pm10_standard: builtins.int = ..., - pm25_standard: builtins.int = ..., - pm100_standard: builtins.int = ..., - pm10_environmental: builtins.int = ..., - pm25_environmental: builtins.int = ..., - pm100_environmental: builtins.int = ..., - particles_03um: builtins.int = ..., - particles_05um: builtins.int = ..., - particles_10um: builtins.int = ..., - particles_25um: builtins.int = ..., - particles_50um: builtins.int = ..., - particles_100um: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["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: ... - -global___AirQualityMetrics = AirQualityMetrics - -@typing_extensions.final -class Telemetry(google.protobuf.message.Message): - """ - Types of Measurements the telemetry module is equipped to handle - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TIME_FIELD_NUMBER: builtins.int - DEVICE_METRICS_FIELD_NUMBER: builtins.int - ENVIRONMENT_METRICS_FIELD_NUMBER: builtins.int - AIR_QUALITY_METRICS_FIELD_NUMBER: builtins.int - POWER_METRICS_FIELD_NUMBER: builtins.int - time: builtins.int - """ - Seconds since 1970 - or 0 for unknown/unset - """ - @property - def device_metrics(self) -> global___DeviceMetrics: - """ - Key native device metrics such as battery level - """ - @property - def environment_metrics(self) -> global___EnvironmentMetrics: - """ - Weather station or other environmental metrics - """ - @property - def air_quality_metrics(self) -> global___AirQualityMetrics: - """ - Air quality metrics - """ - @property - def power_metrics(self) -> global___PowerMetrics: - """ - Power Metrics - """ - def __init__( - self, - *, - time: builtins.int = ..., - device_metrics: global___DeviceMetrics | None = ..., - environment_metrics: global___EnvironmentMetrics | None = ..., - air_quality_metrics: global___AirQualityMetrics | None = ..., - power_metrics: global___PowerMetrics | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "power_metrics", b"power_metrics", "variant", b"variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "power_metrics", b"power_metrics", "time", b"time", "variant", b"variant"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["variant", b"variant"]) -> typing_extensions.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics"] | None: ... - -global___Telemetry = Telemetry diff --git a/meshtastic/xmodem_pb2.py b/meshtastic/xmodem_pb2.py deleted file mode 100644 index a352c63..0000000 --- a/meshtastic/xmodem_pb2.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: meshtastic/xmodem.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -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 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17meshtastic/xmodem.proto\x12\nmeshtastic\"\xb6\x01\n\x06XModem\x12+\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32\x1a.meshtastic.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') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.xmodem_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _XMODEM._serialized_start=40 - _XMODEM._serialized_end=222 - _XMODEM_CONTROL._serialized_start=139 - _XMODEM_CONTROL._serialized_end=222 -# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/xmodem_pb2.pyi b/meshtastic/xmodem_pb2.pyi deleted file mode 100644 index 07d76bd..0000000 --- a/meshtastic/xmodem_pb2.pyi +++ /dev/null @@ -1,66 +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 - -@typing_extensions.final -class XModem(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _Control: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _ControlEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[XModem._Control.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - NUL: XModem._Control.ValueType # 0 - SOH: XModem._Control.ValueType # 1 - STX: XModem._Control.ValueType # 2 - EOT: XModem._Control.ValueType # 4 - ACK: XModem._Control.ValueType # 6 - NAK: XModem._Control.ValueType # 21 - CAN: XModem._Control.ValueType # 24 - CTRLZ: XModem._Control.ValueType # 26 - - class Control(_Control, metaclass=_ControlEnumTypeWrapper): ... - NUL: XModem.Control.ValueType # 0 - SOH: XModem.Control.ValueType # 1 - STX: XModem.Control.ValueType # 2 - EOT: XModem.Control.ValueType # 4 - ACK: XModem.Control.ValueType # 6 - NAK: XModem.Control.ValueType # 21 - CAN: XModem.Control.ValueType # 24 - CTRLZ: XModem.Control.ValueType # 26 - - CONTROL_FIELD_NUMBER: builtins.int - SEQ_FIELD_NUMBER: builtins.int - CRC16_FIELD_NUMBER: builtins.int - BUFFER_FIELD_NUMBER: builtins.int - control: global___XModem.Control.ValueType - seq: builtins.int - crc16: builtins.int - buffer: builtins.bytes - def __init__( - self, - *, - control: global___XModem.Control.ValueType = ..., - seq: builtins.int = ..., - crc16: builtins.int = ..., - buffer: builtins.bytes = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["buffer", b"buffer", "control", b"control", "crc16", b"crc16", "seq", b"seq"]) -> None: ... - -global___XModem = XModem From 96afa703badc3dc083b6bfffb2d4526eeff6b8cb Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 19:07:35 -0700 Subject: [PATCH 063/248] output version number in correct format for github actions, hopefully --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8cdf3da..807b1fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: - name: Get version id: get_version run: >- - poetry version --short + poetry version --short | sed 's/^/::set-output name=version::/' - name: Create GitHub release uses: actions/create-release@v1 From c3dcafb5ef9285922648cfd5d5b2c2a003f14b96 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 26 Jun 2024 02:08:30 +0000 Subject: [PATCH 064/248] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a22ddd0..dc1f2ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.11" +version = "2.3.12" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From f5febc566fa9fe5477a09f9c00465cd8cb11c000 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 25 Jun 2024 19:13:23 -0700 Subject: [PATCH 065/248] comment out windows build for next release, we've been deleting it out of the releases anyway --- .github/workflows/release.yml | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 807b1fb..889bb3b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -152,31 +152,31 @@ jobs: asset_name: readme.txt asset_content_type: text/plain - build-and-publish-windows: - runs-on: windows-latest - needs: release_create - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ needs.release_create.outputs.new_sha }} + # build-and-publish-windows: + # runs-on: windows-latest + # needs: release_create + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # with: + # ref: ${{ needs.release_create.outputs.new_sha }} - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" + # - name: Set up Python 3.9 + # uses: actions/setup-python@v5 + # with: + # python-version: "3.9" - - name: Build - run: | - pip install poetry - bin/build-bin.sh + # - name: Build + # run: | + # pip install poetry + # bin/build-bin.sh - - name: Add windows to release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release_create.outputs.upload_url }} - asset_path: dist/meshtastic.exe - asset_name: meshtastic_windows - asset_content_type: application/zip + # - name: Add windows to release + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ needs.release_create.outputs.upload_url }} + # asset_path: dist/meshtastic.exe + # asset_name: meshtastic_windows + # asset_content_type: application/zip From 88b73611f0f085e9413b7ed982a00b1f98e239a9 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 09:43:56 -0700 Subject: [PATCH 066/248] Move protobufs to meshtastic.protobuf python namespace --- .github/workflows/update_protobufs.yml | 2 +- bin/regen-protobufs.sh | 48 ++++++++++++++++++----- meshtastic/__init__.py | 9 +++-- meshtastic/__main__.py | 3 +- meshtastic/mesh_interface.py | 5 ++- meshtastic/node.py | 2 +- meshtastic/remote_hardware.py | 2 +- meshtastic/tests/test_main.py | 2 +- meshtastic/tests/test_mesh_interface.py | 3 +- meshtastic/tests/test_node.py | 4 +- meshtastic/tests/test_serial_interface.py | 2 +- meshtastic/tests/test_tcp_interface.py | 2 +- meshtastic/tests/test_util.py | 4 +- meshtastic/tunnel.py | 3 +- 14 files changed, 65 insertions(+), 26 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 5cec898..c7b9375 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -37,5 +37,5 @@ jobs: git config --global user.email 'bot@noreply.github.com' git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} git add protobufs - git add meshtastic + git add meshtastic/protobuf git commit -m "Update protobuf submodule" && git push || echo "No changes to commit" diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index 6b993c8..a41f7ba 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + #Uncomment to run hack #gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/* #gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/* @@ -7,17 +9,45 @@ # protoc looks for mypy plugin in the python path source $(poetry env info --path)/bin/activate -./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./ --mypy_out ./ ./protobufs/meshtastic/*.proto -./nanopb-0.4.8/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ --mypy_out ./meshtastic/ ./protobufs/nanopb.proto +# Put our temp files in the poetry build directory +TMPDIR=./build/meshtastic/protofixup +echo "Fixing up protobuf paths in ${TMPDIR} temp directory" -# workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 +# Ensure a clean build +rm -r "${TMPDIR}" + +INDIR=${TMPDIR}/in/meshtastic/protobuf +OUTDIR=${TMPDIR}/out +PYIDIR=${TMPDIR}/out +mkdir -p "${OUTDIR}" "${INDIR}" "${PYIDIR}" +cp ./protobufs/meshtastic/*.proto "${INDIR}" + +# OS-X sed is apparently a little different and expects an arg for -i if [[ $OSTYPE == 'darwin'* ]]; then - sed -i '' -E 's/^(import.*_pb2)/from . \1/' meshtastic/*.py - # automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/protobufs/issues/27) - sed -i '' -E "s/^None = 0/globals()['None'] = 0/" meshtastic/mesh_pb2.py + SEDCMD="sed -i '' -E" else - sed -i -e 's/^import.*_pb2/from . \0/' meshtastic/*.py - # automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/protobufs/issues/27) - sed -i -e "s/^None = 0/globals()['None'] = 0/" meshtastic/mesh_pb2.py + SEDCMD="sed -i -E" fi + + +# change the package names to meshtastic.protobuf +$SEDCMD 's/^package meshtastic;/package meshtastic.protobuf;/' "${INDIR}/"*.proto +# fix the imports to match +$SEDCMD 's/^import "meshtastic\//import "meshtastic\/protobuf\//' "${INDIR}/"*.proto + +# Generate the python files +./nanopb-0.4.8/generator-bin/protoc -I=$TMPDIR/in --python_out "${OUTDIR}" "--mypy_out=${PYIDIR}" $INDIR/*.proto + +# Change "from meshtastic.protobuf import" to "from . import" +$SEDCMD 's/^from meshtastic.protobuf import/from . import/' "${OUTDIR}"/meshtastic/protobuf/*pb2*.py[i] + +# Create a __init__.py in the out directory +touch "${OUTDIR}/meshtastic/protobuf/__init__.py" + +# Copy to the source controlled tree +mkdir -p meshtastic/protobuf +rm -rf meshtastic/protobuf/*pb2*.py +cp "${OUTDIR}/meshtastic/protobuf"/* meshtastic/protobuf + +exit 0 diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 313cb42..e445aa7 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -81,7 +81,10 @@ from google.protobuf.json_format import MessageToJson from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate -from meshtastic import ( +from meshtastic.node import Node +from meshtastic.util import DeferredExecution, Timeout, catchAndIgnore, fixme, stripnl + +from .protobuf import ( admin_pb2, apponly_pb2, channel_pb2, @@ -93,10 +96,10 @@ from meshtastic import ( remote_hardware_pb2, storeforward_pb2, telemetry_pb2, +) +from . import ( util, ) -from meshtastic.node import Node -from meshtastic.util import DeferredExecution, Timeout, catchAndIgnore, fixme, stripnl # Note: To follow PEP224, comments should be after the module variable. diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fa71adc..781f6bf 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -17,7 +17,8 @@ from pubsub import pub # type: ignore[import-untyped] import meshtastic.test import meshtastic.util from meshtastic import mt_config -from meshtastic import channel_pb2, config_pb2, portnums_pb2, remote_hardware, BROADCAST_ADDR +from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 +from meshtastic import remote_hardware, BROADCAST_ADDR from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 66ce7f2..49e87fd 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -18,10 +18,13 @@ from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate import meshtastic.node -from meshtastic import ( + +from meshtastic.protobuf import ( mesh_pb2, portnums_pb2, telemetry_pb2, +) +from meshtastic import ( BROADCAST_ADDR, BROADCAST_NUM, LOCAL_ADDR, diff --git a/meshtastic/node.py b/meshtastic/node.py index 419b712..31a5b03 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -7,7 +7,7 @@ import time from typing import Union -from meshtastic import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2 +from meshtastic.protobuf import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2 from meshtastic.util import ( Timeout, camel_to_snake, diff --git a/meshtastic/remote_hardware.py b/meshtastic/remote_hardware.py index 55c8c18..73836f3 100644 --- a/meshtastic/remote_hardware.py +++ b/meshtastic/remote_hardware.py @@ -4,7 +4,7 @@ import logging from pubsub import pub # type: ignore[import-untyped] -from meshtastic import portnums_pb2, remote_hardware_pb2 +from meshtastic.protobuf import portnums_pb2, remote_hardware_pb2 from meshtastic.util import our_exit diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 18fa497..6f2dd26 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -21,7 +21,7 @@ from meshtastic.__main__ import ( ) from meshtastic import mt_config -from ..channel_pb2 import Channel # pylint: disable=E0611 +from ..protobuf.channel_pb2 import Channel # pylint: disable=E0611 # from ..ble_interface import BLEInterface from ..node import Node diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 5e8441c..2f8dc83 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -7,7 +7,8 @@ from unittest.mock import MagicMock, patch import pytest from hypothesis import given, strategies as st -from .. import mesh_pb2, config_pb2, BROADCAST_ADDR, LOCAL_ADDR +from ..protobuf import mesh_pb2, config_pb2 +from .. import BROADCAST_ADDR, LOCAL_ADDR from ..mesh_interface import MeshInterface, _timeago from ..node import Node diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index 5bacd9d..df3dffb 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -6,8 +6,8 @@ from unittest.mock import MagicMock, patch import pytest -from .. import localonly_pb2, config_pb2 -from ..channel_pb2 import Channel # pylint: disable=E0611 +from ..protobuf import localonly_pb2, config_pb2 +from ..protobuf.channel_pb2 import Channel # pylint: disable=E0611 from ..node import Node from ..serial_interface import SerialInterface from ..mesh_interface import MeshInterface diff --git a/meshtastic/tests/test_serial_interface.py b/meshtastic/tests/test_serial_interface.py index 739380c..797c6d7 100644 --- a/meshtastic/tests/test_serial_interface.py +++ b/meshtastic/tests/test_serial_interface.py @@ -6,7 +6,7 @@ from unittest.mock import mock_open, patch import pytest from ..serial_interface import SerialInterface -from .. import config_pb2 +from ..protobuf import config_pb2 @pytest.mark.unit diff --git a/meshtastic/tests/test_tcp_interface.py b/meshtastic/tests/test_tcp_interface.py index 03d317c..44e79de 100644 --- a/meshtastic/tests/test_tcp_interface.py +++ b/meshtastic/tests/test_tcp_interface.py @@ -5,7 +5,7 @@ from unittest.mock import patch import pytest -from .. import config_pb2 +from ..protobuf import config_pb2 from ..tcp_interface import TCPInterface diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index 74f66d9..1ea80da 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -9,7 +9,7 @@ import pytest from hypothesis import given, strategies as st from meshtastic.supported_device import SupportedDevice -from meshtastic.mesh_pb2 import MyNodeInfo +from meshtastic.protobuf import mesh_pb2 from meshtastic.util import ( Timeout, active_ports_on_supported_devices, @@ -555,7 +555,7 @@ def test_active_ports_on_supported_devices_mac_duplicates_check(mock_platform, m @pytest.mark.unit 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(MyNodeInfo())) + actual = json.loads(message_to_json(mesh_pb2.MyNodeInfo())) expected = { "myNodeNum": 0, "rebootCount": 0, "minAppVersion": 0 } assert actual == expected diff --git a/meshtastic/tunnel.py b/meshtastic/tunnel.py index 40a1c2e..409e3d4 100644 --- a/meshtastic/tunnel.py +++ b/meshtastic/tunnel.py @@ -22,7 +22,8 @@ import threading from pubsub import pub # type: ignore[import-untyped] from pytap2 import TapDevice -from meshtastic import portnums_pb2, mt_config +from meshtastic.protobuf import portnums_pb2 +from meshtastic import mt_config from meshtastic.util import ipstr, readnet_u16 From 6d846c3a63305597328eb723cf56e025b241204d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 10:12:24 -0700 Subject: [PATCH 067/248] manually rebuild the protobuf glue files for now... (see PR for info) --- meshtastic/protobuf/__init__.py | 0 meshtastic/protobuf/admin_pb2.py | 39 + meshtastic/protobuf/admin_pb2.pyi | 572 ++++ meshtastic/protobuf/apponly_pb2.py | 28 + meshtastic/protobuf/apponly_pb2.pyi | 52 + meshtastic/protobuf/atak_pb2.py | 40 + meshtastic/protobuf/atak_pb2.pyi | 470 +++ meshtastic/protobuf/cannedmessages_pb2.py | 26 + meshtastic/protobuf/cannedmessages_pb2.pyi | 33 + meshtastic/protobuf/channel_pb2.py | 34 + meshtastic/protobuf/channel_pb2.pyi | 234 ++ meshtastic/protobuf/clientonly_pb2.py | 27 + meshtastic/protobuf/clientonly_pb2.pyi | 74 + meshtastic/protobuf/config_pb2.py | 70 + meshtastic/protobuf/config_pb2.pyi | 1511 ++++++++++ meshtastic/protobuf/connection_status_pb2.py | 36 + meshtastic/protobuf/connection_status_pb2.pyi | 228 ++ meshtastic/protobuf/deviceonly_pb2.py | 46 + meshtastic/protobuf/deviceonly_pb2.pyi | 400 +++ meshtastic/protobuf/localonly_pb2.py | 30 + meshtastic/protobuf/localonly_pb2.pyi | 220 ++ meshtastic/protobuf/mesh_pb2.py | 98 + meshtastic/protobuf/mesh_pb2.pyi | 2552 +++++++++++++++++ meshtastic/protobuf/module_config_pb2.py | 66 + meshtastic/protobuf/module_config_pb2.pyi | 1200 ++++++++ meshtastic/protobuf/mqtt_pb2.py | 30 + meshtastic/protobuf/mqtt_pb2.pyi | 148 + meshtastic/protobuf/paxcount_pb2.py | 26 + meshtastic/protobuf/paxcount_pb2.pyi | 45 + meshtastic/protobuf/portnums_pb2.py | 26 + meshtastic/protobuf/portnums_pb2.pyi | 370 +++ meshtastic/protobuf/remote_hardware_pb2.py | 28 + meshtastic/protobuf/remote_hardware_pb2.pyi | 126 + meshtastic/protobuf/rtttl_pb2.py | 26 + meshtastic/protobuf/rtttl_pb2.pyi | 33 + meshtastic/protobuf/storeforward_pb2.py | 34 + meshtastic/protobuf/storeforward_pb2.pyi | 345 +++ meshtastic/protobuf/telemetry_pb2.py | 36 + meshtastic/protobuf/telemetry_pb2.pyi | 576 ++++ meshtastic/protobuf/xmodem_pb2.py | 28 + meshtastic/protobuf/xmodem_pb2.pyi | 67 + 41 files changed, 10030 insertions(+) create mode 100644 meshtastic/protobuf/__init__.py create mode 100644 meshtastic/protobuf/admin_pb2.py create mode 100644 meshtastic/protobuf/admin_pb2.pyi create mode 100644 meshtastic/protobuf/apponly_pb2.py create mode 100644 meshtastic/protobuf/apponly_pb2.pyi create mode 100644 meshtastic/protobuf/atak_pb2.py create mode 100644 meshtastic/protobuf/atak_pb2.pyi create mode 100644 meshtastic/protobuf/cannedmessages_pb2.py create mode 100644 meshtastic/protobuf/cannedmessages_pb2.pyi create mode 100644 meshtastic/protobuf/channel_pb2.py create mode 100644 meshtastic/protobuf/channel_pb2.pyi create mode 100644 meshtastic/protobuf/clientonly_pb2.py create mode 100644 meshtastic/protobuf/clientonly_pb2.pyi create mode 100644 meshtastic/protobuf/config_pb2.py create mode 100644 meshtastic/protobuf/config_pb2.pyi create mode 100644 meshtastic/protobuf/connection_status_pb2.py create mode 100644 meshtastic/protobuf/connection_status_pb2.pyi create mode 100644 meshtastic/protobuf/deviceonly_pb2.py create mode 100644 meshtastic/protobuf/deviceonly_pb2.pyi create mode 100644 meshtastic/protobuf/localonly_pb2.py create mode 100644 meshtastic/protobuf/localonly_pb2.pyi create mode 100644 meshtastic/protobuf/mesh_pb2.py create mode 100644 meshtastic/protobuf/mesh_pb2.pyi create mode 100644 meshtastic/protobuf/module_config_pb2.py create mode 100644 meshtastic/protobuf/module_config_pb2.pyi create mode 100644 meshtastic/protobuf/mqtt_pb2.py create mode 100644 meshtastic/protobuf/mqtt_pb2.pyi create mode 100644 meshtastic/protobuf/paxcount_pb2.py create mode 100644 meshtastic/protobuf/paxcount_pb2.pyi create mode 100644 meshtastic/protobuf/portnums_pb2.py create mode 100644 meshtastic/protobuf/portnums_pb2.pyi create mode 100644 meshtastic/protobuf/remote_hardware_pb2.py create mode 100644 meshtastic/protobuf/remote_hardware_pb2.pyi create mode 100644 meshtastic/protobuf/rtttl_pb2.py create mode 100644 meshtastic/protobuf/rtttl_pb2.pyi create mode 100644 meshtastic/protobuf/storeforward_pb2.py create mode 100644 meshtastic/protobuf/storeforward_pb2.pyi create mode 100644 meshtastic/protobuf/telemetry_pb2.py create mode 100644 meshtastic/protobuf/telemetry_pb2.pyi create mode 100644 meshtastic/protobuf/xmodem_pb2.py create mode 100644 meshtastic/protobuf/xmodem_pb2.pyi diff --git a/meshtastic/protobuf/__init__.py b/meshtastic/protobuf/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py new file mode 100644 index 0000000..1429f1e --- /dev/null +++ b/meshtastic/protobuf/admin_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/admin.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 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 connection_status_pb2 as meshtastic_dot_protobuf_dot_connection__status__pb2 +from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2 +from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xd5\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"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.admin_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_ADMINMESSAGE']._serialized_start=244 + _globals['_ADMINMESSAGE']._serialized_end=2633 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2147 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2296 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2299 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2614 + _globals['_HAMPARAMETERS']._serialized_start=2635 + _globals['_HAMPARAMETERS']._serialized_end=2726 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2728 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2839 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi new file mode 100644 index 0000000..cdfc6b7 --- /dev/null +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -0,0 +1,572 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import meshtastic.protobuf.channel_pb2 +import meshtastic.protobuf.config_pb2 +import meshtastic.protobuf.connection_status_pb2 +import meshtastic.protobuf.mesh_pb2 +import meshtastic.protobuf.module_config_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class AdminMessage(google.protobuf.message.Message): + """ + This message is handled by the Admin module and is responsible for all settings/channel read/write operations. + This message is used to do settings operations to both remote AND local nodes. + (Prior to 1.2 these operations were done via special ToRadio operations) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _ConfigType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ConfigTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AdminMessage._ConfigType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DEVICE_CONFIG: AdminMessage._ConfigType.ValueType # 0 + """ + TODO: REPLACE + """ + POSITION_CONFIG: AdminMessage._ConfigType.ValueType # 1 + """ + TODO: REPLACE + """ + POWER_CONFIG: AdminMessage._ConfigType.ValueType # 2 + """ + TODO: REPLACE + """ + NETWORK_CONFIG: AdminMessage._ConfigType.ValueType # 3 + """ + TODO: REPLACE + """ + DISPLAY_CONFIG: AdminMessage._ConfigType.ValueType # 4 + """ + TODO: REPLACE + """ + LORA_CONFIG: AdminMessage._ConfigType.ValueType # 5 + """ + TODO: REPLACE + """ + BLUETOOTH_CONFIG: AdminMessage._ConfigType.ValueType # 6 + """ + TODO: REPLACE + """ + + class ConfigType(_ConfigType, metaclass=_ConfigTypeEnumTypeWrapper): + """ + TODO: REPLACE + """ + + DEVICE_CONFIG: AdminMessage.ConfigType.ValueType # 0 + """ + TODO: REPLACE + """ + POSITION_CONFIG: AdminMessage.ConfigType.ValueType # 1 + """ + TODO: REPLACE + """ + POWER_CONFIG: AdminMessage.ConfigType.ValueType # 2 + """ + TODO: REPLACE + """ + NETWORK_CONFIG: AdminMessage.ConfigType.ValueType # 3 + """ + TODO: REPLACE + """ + DISPLAY_CONFIG: AdminMessage.ConfigType.ValueType # 4 + """ + TODO: REPLACE + """ + LORA_CONFIG: AdminMessage.ConfigType.ValueType # 5 + """ + TODO: REPLACE + """ + BLUETOOTH_CONFIG: AdminMessage.ConfigType.ValueType # 6 + """ + TODO: REPLACE + """ + + class _ModuleConfigType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ModuleConfigTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AdminMessage._ModuleConfigType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + MQTT_CONFIG: AdminMessage._ModuleConfigType.ValueType # 0 + """ + TODO: REPLACE + """ + SERIAL_CONFIG: AdminMessage._ModuleConfigType.ValueType # 1 + """ + TODO: REPLACE + """ + EXTNOTIF_CONFIG: AdminMessage._ModuleConfigType.ValueType # 2 + """ + TODO: REPLACE + """ + STOREFORWARD_CONFIG: AdminMessage._ModuleConfigType.ValueType # 3 + """ + TODO: REPLACE + """ + RANGETEST_CONFIG: AdminMessage._ModuleConfigType.ValueType # 4 + """ + TODO: REPLACE + """ + TELEMETRY_CONFIG: AdminMessage._ModuleConfigType.ValueType # 5 + """ + TODO: REPLACE + """ + CANNEDMSG_CONFIG: AdminMessage._ModuleConfigType.ValueType # 6 + """ + TODO: REPLACE + """ + AUDIO_CONFIG: AdminMessage._ModuleConfigType.ValueType # 7 + """ + TODO: REPLACE + """ + REMOTEHARDWARE_CONFIG: AdminMessage._ModuleConfigType.ValueType # 8 + """ + TODO: REPLACE + """ + NEIGHBORINFO_CONFIG: AdminMessage._ModuleConfigType.ValueType # 9 + """ + TODO: REPLACE + """ + AMBIENTLIGHTING_CONFIG: AdminMessage._ModuleConfigType.ValueType # 10 + """ + TODO: REPLACE + """ + DETECTIONSENSOR_CONFIG: AdminMessage._ModuleConfigType.ValueType # 11 + """ + TODO: REPLACE + """ + PAXCOUNTER_CONFIG: AdminMessage._ModuleConfigType.ValueType # 12 + """ + TODO: REPLACE + """ + + class ModuleConfigType(_ModuleConfigType, metaclass=_ModuleConfigTypeEnumTypeWrapper): + """ + TODO: REPLACE + """ + + MQTT_CONFIG: AdminMessage.ModuleConfigType.ValueType # 0 + """ + TODO: REPLACE + """ + SERIAL_CONFIG: AdminMessage.ModuleConfigType.ValueType # 1 + """ + TODO: REPLACE + """ + EXTNOTIF_CONFIG: AdminMessage.ModuleConfigType.ValueType # 2 + """ + TODO: REPLACE + """ + STOREFORWARD_CONFIG: AdminMessage.ModuleConfigType.ValueType # 3 + """ + TODO: REPLACE + """ + RANGETEST_CONFIG: AdminMessage.ModuleConfigType.ValueType # 4 + """ + TODO: REPLACE + """ + TELEMETRY_CONFIG: AdminMessage.ModuleConfigType.ValueType # 5 + """ + TODO: REPLACE + """ + CANNEDMSG_CONFIG: AdminMessage.ModuleConfigType.ValueType # 6 + """ + TODO: REPLACE + """ + AUDIO_CONFIG: AdminMessage.ModuleConfigType.ValueType # 7 + """ + TODO: REPLACE + """ + REMOTEHARDWARE_CONFIG: AdminMessage.ModuleConfigType.ValueType # 8 + """ + TODO: REPLACE + """ + NEIGHBORINFO_CONFIG: AdminMessage.ModuleConfigType.ValueType # 9 + """ + TODO: REPLACE + """ + AMBIENTLIGHTING_CONFIG: AdminMessage.ModuleConfigType.ValueType # 10 + """ + TODO: REPLACE + """ + DETECTIONSENSOR_CONFIG: AdminMessage.ModuleConfigType.ValueType # 11 + """ + TODO: REPLACE + """ + PAXCOUNTER_CONFIG: AdminMessage.ModuleConfigType.ValueType # 12 + """ + TODO: REPLACE + """ + + GET_CHANNEL_REQUEST_FIELD_NUMBER: builtins.int + GET_CHANNEL_RESPONSE_FIELD_NUMBER: builtins.int + GET_OWNER_REQUEST_FIELD_NUMBER: builtins.int + GET_OWNER_RESPONSE_FIELD_NUMBER: builtins.int + GET_CONFIG_REQUEST_FIELD_NUMBER: builtins.int + GET_CONFIG_RESPONSE_FIELD_NUMBER: builtins.int + GET_MODULE_CONFIG_REQUEST_FIELD_NUMBER: builtins.int + GET_MODULE_CONFIG_RESPONSE_FIELD_NUMBER: builtins.int + GET_CANNED_MESSAGE_MODULE_MESSAGES_REQUEST_FIELD_NUMBER: builtins.int + GET_CANNED_MESSAGE_MODULE_MESSAGES_RESPONSE_FIELD_NUMBER: builtins.int + GET_DEVICE_METADATA_REQUEST_FIELD_NUMBER: builtins.int + GET_DEVICE_METADATA_RESPONSE_FIELD_NUMBER: builtins.int + GET_RINGTONE_REQUEST_FIELD_NUMBER: builtins.int + GET_RINGTONE_RESPONSE_FIELD_NUMBER: builtins.int + GET_DEVICE_CONNECTION_STATUS_REQUEST_FIELD_NUMBER: builtins.int + GET_DEVICE_CONNECTION_STATUS_RESPONSE_FIELD_NUMBER: builtins.int + SET_HAM_MODE_FIELD_NUMBER: builtins.int + GET_NODE_REMOTE_HARDWARE_PINS_REQUEST_FIELD_NUMBER: builtins.int + GET_NODE_REMOTE_HARDWARE_PINS_RESPONSE_FIELD_NUMBER: builtins.int + ENTER_DFU_MODE_REQUEST_FIELD_NUMBER: builtins.int + DELETE_FILE_REQUEST_FIELD_NUMBER: builtins.int + SET_OWNER_FIELD_NUMBER: builtins.int + SET_CHANNEL_FIELD_NUMBER: builtins.int + SET_CONFIG_FIELD_NUMBER: builtins.int + SET_MODULE_CONFIG_FIELD_NUMBER: builtins.int + SET_CANNED_MESSAGE_MODULE_MESSAGES_FIELD_NUMBER: builtins.int + SET_RINGTONE_MESSAGE_FIELD_NUMBER: builtins.int + REMOVE_BY_NODENUM_FIELD_NUMBER: builtins.int + SET_FAVORITE_NODE_FIELD_NUMBER: builtins.int + REMOVE_FAVORITE_NODE_FIELD_NUMBER: builtins.int + SET_FIXED_POSITION_FIELD_NUMBER: builtins.int + REMOVE_FIXED_POSITION_FIELD_NUMBER: builtins.int + BEGIN_EDIT_SETTINGS_FIELD_NUMBER: builtins.int + COMMIT_EDIT_SETTINGS_FIELD_NUMBER: builtins.int + REBOOT_OTA_SECONDS_FIELD_NUMBER: builtins.int + EXIT_SIMULATOR_FIELD_NUMBER: builtins.int + REBOOT_SECONDS_FIELD_NUMBER: builtins.int + SHUTDOWN_SECONDS_FIELD_NUMBER: builtins.int + FACTORY_RESET_FIELD_NUMBER: builtins.int + NODEDB_RESET_FIELD_NUMBER: builtins.int + get_channel_request: builtins.int + """ + Send the specified channel in the response to this message + NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) + """ + get_owner_request: builtins.bool + """ + Send the current owner data in the response to this message. + """ + get_config_request: global___AdminMessage.ConfigType.ValueType + """ + Ask for the following config data to be sent + """ + get_module_config_request: global___AdminMessage.ModuleConfigType.ValueType + """ + Ask for the following config data to be sent + """ + get_canned_message_module_messages_request: builtins.bool + """ + Get the Canned Message Module messages in the response to this message. + """ + get_canned_message_module_messages_response: builtins.str + """ + Get the Canned Message Module messages in the response to this message. + """ + get_device_metadata_request: builtins.bool + """ + Request the node to send device metadata (firmware, protobuf version, etc) + """ + get_ringtone_request: builtins.bool + """ + Get the Ringtone in the response to this message. + """ + get_ringtone_response: builtins.str + """ + Get the Ringtone in the response to this message. + """ + get_device_connection_status_request: builtins.bool + """ + Request the node to send it's connection status + """ + get_node_remote_hardware_pins_request: builtins.bool + """ + Get the mesh's nodes with their available gpio pins for RemoteHardware module use + """ + enter_dfu_mode_request: builtins.bool + """ + Enter (UF2) DFU mode + Only implemented on NRF52 currently + """ + delete_file_request: builtins.str + """ + Delete the file by the specified path from the device + """ + set_canned_message_module_messages: builtins.str + """ + Set the Canned Message Module messages text. + """ + set_ringtone_message: builtins.str + """ + Set the ringtone for ExternalNotification. + """ + remove_by_nodenum: builtins.int + """ + Remove the node by the specified node-num from the NodeDB on the device + """ + set_favorite_node: builtins.int + """ + Set specified node-num to be favorited on the NodeDB on the device + """ + remove_favorite_node: builtins.int + """ + Set specified node-num to be un-favorited on the NodeDB on the device + """ + remove_fixed_position: builtins.bool + """ + Clear fixed position coordinates and then set position.fixed_position = false + """ + begin_edit_settings: builtins.bool + """ + Begins an edit transaction for config, module config, owner, and channel settings changes + This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) + """ + commit_edit_settings: builtins.bool + """ + Commits an open transaction for any edits made to config, module config, owner, and channel settings + """ + reboot_ota_seconds: builtins.int + """ + Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) + Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. + """ + exit_simulator: builtins.bool + """ + This message is only supported for the simulator Portduino build. + If received the simulator will exit successfully. + """ + reboot_seconds: builtins.int + """ + Tell the node to reboot in this many seconds (or <0 to cancel reboot) + """ + shutdown_seconds: builtins.int + """ + Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) + """ + factory_reset: builtins.int + """ + Tell the node to factory reset, all device settings will be returned to factory defaults. + """ + nodedb_reset: builtins.int + """ + Tell the node to reset the nodedb. + """ + @property + def get_channel_response(self) -> meshtastic.protobuf.channel_pb2.Channel: + """ + TODO: REPLACE + """ + + @property + def get_owner_response(self) -> meshtastic.protobuf.mesh_pb2.User: + """ + TODO: REPLACE + """ + + @property + def get_config_response(self) -> meshtastic.protobuf.config_pb2.Config: + """ + Send the current Config in the response to this message. + """ + + @property + def get_module_config_response(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig: + """ + Send the current Config in the response to this message. + """ + + @property + def get_device_metadata_response(self) -> meshtastic.protobuf.mesh_pb2.DeviceMetadata: + """ + Device metadata response + """ + + @property + def get_device_connection_status_response(self) -> meshtastic.protobuf.connection_status_pb2.DeviceConnectionStatus: + """ + Device connection status response + """ + + @property + def set_ham_mode(self) -> global___HamParameters: + """ + Setup a node for licensed amateur (ham) radio operation + """ + + @property + def get_node_remote_hardware_pins_response(self) -> global___NodeRemoteHardwarePinsResponse: + """ + Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use + """ + + @property + def set_owner(self) -> meshtastic.protobuf.mesh_pb2.User: + """ + Set the owner for this node + """ + + @property + def set_channel(self) -> meshtastic.protobuf.channel_pb2.Channel: + """ + Set channels (using the new API). + A special channel is the "primary channel". + The other records are secondary channels. + Note: only one channel can be marked as primary. + If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. + """ + + @property + def set_config(self) -> meshtastic.protobuf.config_pb2.Config: + """ + Set the current Config + """ + + @property + def set_module_config(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig: + """ + Set the current Config + """ + + @property + def set_fixed_position(self) -> meshtastic.protobuf.mesh_pb2.Position: + """ + Set fixed position data on the node and then set the position.fixed_position = true + """ + + def __init__( + self, + *, + get_channel_request: builtins.int = ..., + get_channel_response: meshtastic.protobuf.channel_pb2.Channel | None = ..., + get_owner_request: builtins.bool = ..., + get_owner_response: meshtastic.protobuf.mesh_pb2.User | None = ..., + get_config_request: global___AdminMessage.ConfigType.ValueType = ..., + get_config_response: meshtastic.protobuf.config_pb2.Config | None = ..., + get_module_config_request: global___AdminMessage.ModuleConfigType.ValueType = ..., + get_module_config_response: meshtastic.protobuf.module_config_pb2.ModuleConfig | None = ..., + get_canned_message_module_messages_request: builtins.bool = ..., + get_canned_message_module_messages_response: builtins.str = ..., + get_device_metadata_request: builtins.bool = ..., + get_device_metadata_response: meshtastic.protobuf.mesh_pb2.DeviceMetadata | None = ..., + get_ringtone_request: builtins.bool = ..., + get_ringtone_response: builtins.str = ..., + get_device_connection_status_request: builtins.bool = ..., + get_device_connection_status_response: meshtastic.protobuf.connection_status_pb2.DeviceConnectionStatus | None = ..., + set_ham_mode: global___HamParameters | None = ..., + get_node_remote_hardware_pins_request: builtins.bool = ..., + get_node_remote_hardware_pins_response: global___NodeRemoteHardwarePinsResponse | None = ..., + enter_dfu_mode_request: builtins.bool = ..., + delete_file_request: builtins.str = ..., + set_owner: meshtastic.protobuf.mesh_pb2.User | None = ..., + set_channel: meshtastic.protobuf.channel_pb2.Channel | None = ..., + set_config: meshtastic.protobuf.config_pb2.Config | None = ..., + set_module_config: meshtastic.protobuf.module_config_pb2.ModuleConfig | None = ..., + set_canned_message_module_messages: builtins.str = ..., + set_ringtone_message: builtins.str = ..., + remove_by_nodenum: builtins.int = ..., + set_favorite_node: builtins.int = ..., + remove_favorite_node: builtins.int = ..., + set_fixed_position: meshtastic.protobuf.mesh_pb2.Position | None = ..., + remove_fixed_position: builtins.bool = ..., + begin_edit_settings: builtins.bool = ..., + commit_edit_settings: builtins.bool = ..., + reboot_ota_seconds: builtins.int = ..., + exit_simulator: builtins.bool = ..., + reboot_seconds: builtins.int = ..., + shutdown_seconds: builtins.int = ..., + factory_reset: builtins.int = ..., + nodedb_reset: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> 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_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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... + +global___AdminMessage = AdminMessage + +@typing.final +class HamParameters(google.protobuf.message.Message): + """ + Parameters for setting up Meshtastic for ameteur radio usage + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CALL_SIGN_FIELD_NUMBER: builtins.int + TX_POWER_FIELD_NUMBER: builtins.int + FREQUENCY_FIELD_NUMBER: builtins.int + SHORT_NAME_FIELD_NUMBER: builtins.int + call_sign: builtins.str + """ + Amateur radio call sign, eg. KD2ABC + """ + tx_power: builtins.int + """ + Transmit power in dBm at the LoRA transceiver, not including any amplification + """ + frequency: builtins.float + """ + The selected frequency of LoRA operation + Please respect your local laws, regulations, and band plans. + Ensure your radio is capable of operating of the selected frequency before setting this. + """ + short_name: builtins.str + """ + Optional short name of user + """ + def __init__( + self, + *, + call_sign: builtins.str = ..., + tx_power: builtins.int = ..., + frequency: builtins.float = ..., + short_name: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["call_sign", b"call_sign", "frequency", b"frequency", "short_name", b"short_name", "tx_power", b"tx_power"]) -> None: ... + +global___HamParameters = HamParameters + +@typing.final +class NodeRemoteHardwarePinsResponse(google.protobuf.message.Message): + """ + Response envelope for node_remote_hardware_pins + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: builtins.int + @property + def node_remote_hardware_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin]: + """ + Nodes and their respective remote hardware GPIO pins + """ + + def __init__( + self, + *, + node_remote_hardware_pins: collections.abc.Iterable[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["node_remote_hardware_pins", b"node_remote_hardware_pins"]) -> None: ... + +global___NodeRemoteHardwarePinsResponse = NodeRemoteHardwarePinsResponse diff --git a/meshtastic/protobuf/apponly_pb2.py b/meshtastic/protobuf/apponly_pb2.py new file mode 100644 index 0000000..151fbf6 --- /dev/null +++ b/meshtastic/protobuf/apponly_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/apponly.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 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 + + +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\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) diff --git a/meshtastic/protobuf/apponly_pb2.pyi b/meshtastic/protobuf/apponly_pb2.pyi new file mode 100644 index 0000000..c8a34bc --- /dev/null +++ b/meshtastic/protobuf/apponly_pb2.pyi @@ -0,0 +1,52 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import meshtastic.protobuf.channel_pb2 +import meshtastic.protobuf.config_pb2 +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class ChannelSet(google.protobuf.message.Message): + """ + This is the most compact possible representation for a set of channels. + It includes only one PRIMARY channel (which must be first) and + any SECONDARY channels. + No DISABLED channels are included. + This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SETTINGS_FIELD_NUMBER: builtins.int + LORA_CONFIG_FIELD_NUMBER: builtins.int + @property + def settings(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.channel_pb2.ChannelSettings]: + """ + Channel list with settings + """ + + @property + def lora_config(self) -> meshtastic.protobuf.config_pb2.Config.LoRaConfig: + """ + LoRa config + """ + + def __init__( + self, + *, + settings: collections.abc.Iterable[meshtastic.protobuf.channel_pb2.ChannelSettings] | None = ..., + lora_config: meshtastic.protobuf.config_pb2.Config.LoRaConfig | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["lora_config", b"lora_config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["lora_config", b"lora_config", "settings", b"settings"]) -> None: ... + +global___ChannelSet = ChannelSet diff --git a/meshtastic/protobuf/atak_pb2.py b/meshtastic/protobuf/atak_pb2.py new file mode 100644 index 0000000..aec03c3 --- /dev/null +++ b/meshtastic/protobuf/atak_pb2.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/atak.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\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\x93\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\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\023com.geeksville.meshB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_TEAM']._serialized_start=703 + _globals['_TEAM']._serialized_end=895 + _globals['_MEMBERROLE']._serialized_start=897 + _globals['_MEMBERROLE']._serialized_end=1024 + _globals['_TAKPACKET']._serialized_start=56 + _globals['_TAKPACKET']._serialized_end=331 + _globals['_GEOCHAT']._serialized_start=333 + _globals['_GEOCHAT']._serialized_end=425 + _globals['_GROUP']._serialized_start=427 + _globals['_GROUP']._serialized_end=522 + _globals['_STATUS']._serialized_start=524 + _globals['_STATUS']._serialized_end=549 + _globals['_CONTACT']._serialized_start=551 + _globals['_CONTACT']._serialized_end=603 + _globals['_PLI']._serialized_start=605 + _globals['_PLI']._serialized_end=700 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/atak_pb2.pyi b/meshtastic/protobuf/atak_pb2.pyi new file mode 100644 index 0000000..4471e17 --- /dev/null +++ b/meshtastic/protobuf/atak_pb2.pyi @@ -0,0 +1,470 @@ +""" +@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 _Team: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TeamEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Team.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Unspecifed_Color: _Team.ValueType # 0 + """ + Unspecifed + """ + White: _Team.ValueType # 1 + """ + White + """ + Yellow: _Team.ValueType # 2 + """ + Yellow + """ + Orange: _Team.ValueType # 3 + """ + Orange + """ + Magenta: _Team.ValueType # 4 + """ + Magenta + """ + Red: _Team.ValueType # 5 + """ + Red + """ + Maroon: _Team.ValueType # 6 + """ + Maroon + """ + Purple: _Team.ValueType # 7 + """ + Purple + """ + Dark_Blue: _Team.ValueType # 8 + """ + Dark Blue + """ + Blue: _Team.ValueType # 9 + """ + Blue + """ + Cyan: _Team.ValueType # 10 + """ + Cyan + """ + Teal: _Team.ValueType # 11 + """ + Teal + """ + Green: _Team.ValueType # 12 + """ + Green + """ + Dark_Green: _Team.ValueType # 13 + """ + Dark Green + """ + Brown: _Team.ValueType # 14 + """ + Brown + """ + +class Team(_Team, metaclass=_TeamEnumTypeWrapper): ... + +Unspecifed_Color: Team.ValueType # 0 +""" +Unspecifed +""" +White: Team.ValueType # 1 +""" +White +""" +Yellow: Team.ValueType # 2 +""" +Yellow +""" +Orange: Team.ValueType # 3 +""" +Orange +""" +Magenta: Team.ValueType # 4 +""" +Magenta +""" +Red: Team.ValueType # 5 +""" +Red +""" +Maroon: Team.ValueType # 6 +""" +Maroon +""" +Purple: Team.ValueType # 7 +""" +Purple +""" +Dark_Blue: Team.ValueType # 8 +""" +Dark Blue +""" +Blue: Team.ValueType # 9 +""" +Blue +""" +Cyan: Team.ValueType # 10 +""" +Cyan +""" +Teal: Team.ValueType # 11 +""" +Teal +""" +Green: Team.ValueType # 12 +""" +Green +""" +Dark_Green: Team.ValueType # 13 +""" +Dark Green +""" +Brown: Team.ValueType # 14 +""" +Brown +""" +global___Team = Team + +class _MemberRole: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _MemberRoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MemberRole.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Unspecifed: _MemberRole.ValueType # 0 + """ + Unspecifed + """ + TeamMember: _MemberRole.ValueType # 1 + """ + Team Member + """ + TeamLead: _MemberRole.ValueType # 2 + """ + Team Lead + """ + HQ: _MemberRole.ValueType # 3 + """ + Headquarters + """ + Sniper: _MemberRole.ValueType # 4 + """ + Airsoft enthusiast + """ + Medic: _MemberRole.ValueType # 5 + """ + Medic + """ + ForwardObserver: _MemberRole.ValueType # 6 + """ + ForwardObserver + """ + RTO: _MemberRole.ValueType # 7 + """ + Radio Telephone Operator + """ + K9: _MemberRole.ValueType # 8 + """ + Doggo + """ + +class MemberRole(_MemberRole, metaclass=_MemberRoleEnumTypeWrapper): + """ + Role of the group member + """ + +Unspecifed: MemberRole.ValueType # 0 +""" +Unspecifed +""" +TeamMember: MemberRole.ValueType # 1 +""" +Team Member +""" +TeamLead: MemberRole.ValueType # 2 +""" +Team Lead +""" +HQ: MemberRole.ValueType # 3 +""" +Headquarters +""" +Sniper: MemberRole.ValueType # 4 +""" +Airsoft enthusiast +""" +Medic: MemberRole.ValueType # 5 +""" +Medic +""" +ForwardObserver: MemberRole.ValueType # 6 +""" +ForwardObserver +""" +RTO: MemberRole.ValueType # 7 +""" +Radio Telephone Operator +""" +K9: MemberRole.ValueType # 8 +""" +Doggo +""" +global___MemberRole = MemberRole + +@typing.final +class TAKPacket(google.protobuf.message.Message): + """ + Packets for the official ATAK Plugin + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IS_COMPRESSED_FIELD_NUMBER: builtins.int + CONTACT_FIELD_NUMBER: builtins.int + GROUP_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + PLI_FIELD_NUMBER: builtins.int + CHAT_FIELD_NUMBER: builtins.int + is_compressed: builtins.bool + """ + Are the payloads strings compressed for LoRA transport? + """ + @property + def contact(self) -> global___Contact: + """ + The contact / callsign for ATAK user + """ + + @property + def group(self) -> global___Group: + """ + The group for ATAK user + """ + + @property + def status(self) -> global___Status: + """ + The status of the ATAK EUD + """ + + @property + def pli(self) -> global___PLI: + """ + TAK position report + """ + + @property + def chat(self) -> global___GeoChat: + """ + ATAK GeoChat message + """ + + def __init__( + self, + *, + is_compressed: builtins.bool = ..., + contact: global___Contact | None = ..., + group: global___Group | None = ..., + status: global___Status | None = ..., + pli: global___PLI | None = ..., + chat: global___GeoChat | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "is_compressed", b"is_compressed", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["pli", "chat"] | None: ... + +global___TAKPacket = TAKPacket + +@typing.final +class GeoChat(google.protobuf.message.Message): + """ + ATAK GeoChat message + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MESSAGE_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + TO_CALLSIGN_FIELD_NUMBER: builtins.int + message: builtins.str + """ + The text message + """ + to: builtins.str + """ + Uid recipient of the message + """ + to_callsign: builtins.str + """ + Callsign of the recipient for the message + """ + def __init__( + self, + *, + message: builtins.str = ..., + to: builtins.str | None = ..., + to_callsign: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "to", b"to", "to_callsign", b"to_callsign"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "message", b"message", "to", b"to", "to_callsign", b"to_callsign"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to_callsign", b"_to_callsign"]) -> typing.Literal["to_callsign"] | None: ... + +global___GeoChat = GeoChat + +@typing.final +class Group(google.protobuf.message.Message): + """ + ATAK Group + <__group role='Team Member' name='Cyan'/> + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROLE_FIELD_NUMBER: builtins.int + TEAM_FIELD_NUMBER: builtins.int + role: global___MemberRole.ValueType + """ + Role of the group member + """ + team: global___Team.ValueType + """ + Team (color) + Default Cyan + """ + def __init__( + self, + *, + role: global___MemberRole.ValueType = ..., + team: global___Team.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["role", b"role", "team", b"team"]) -> None: ... + +global___Group = Group + +@typing.final +class Status(google.protobuf.message.Message): + """ + ATAK EUD Status + + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BATTERY_FIELD_NUMBER: builtins.int + battery: builtins.int + """ + Battery level + """ + def __init__( + self, + *, + battery: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["battery", b"battery"]) -> None: ... + +global___Status = Status + +@typing.final +class Contact(google.protobuf.message.Message): + """ + ATAK Contact + + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CALLSIGN_FIELD_NUMBER: builtins.int + DEVICE_CALLSIGN_FIELD_NUMBER: builtins.int + callsign: builtins.str + """ + Callsign + """ + device_callsign: builtins.str + """ + Device callsign + + IP address of endpoint in integer form (0.0.0.0 default) + """ + def __init__( + self, + *, + callsign: builtins.str = ..., + device_callsign: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["callsign", b"callsign", "device_callsign", b"device_callsign"]) -> None: ... + +global___Contact = Contact + +@typing.final +class PLI(google.protobuf.message.Message): + """ + Position Location Information from ATAK + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + ALTITUDE_FIELD_NUMBER: builtins.int + SPEED_FIELD_NUMBER: builtins.int + COURSE_FIELD_NUMBER: builtins.int + latitude_i: builtins.int + """ + The new preferred location encoding, multiply by 1e-7 to get degrees + in floating point + """ + longitude_i: builtins.int + """ + The new preferred location encoding, multiply by 1e-7 to get degrees + in floating point + """ + altitude: builtins.int + """ + Altitude (ATAK prefers HAE) + """ + speed: builtins.int + """ + Speed + """ + course: builtins.int + """ + Course in degrees + """ + def __init__( + self, + *, + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + altitude: builtins.int = ..., + speed: builtins.int = ..., + course: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "course", b"course", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i", "speed", b"speed"]) -> None: ... + +global___PLI = PLI diff --git a/meshtastic/protobuf/cannedmessages_pb2.py b/meshtastic/protobuf/cannedmessages_pb2.py new file mode 100644 index 0000000..2b32b47 --- /dev/null +++ b/meshtastic/protobuf/cannedmessages_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/cannedmessages.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/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\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) diff --git a/meshtastic/protobuf/cannedmessages_pb2.pyi b/meshtastic/protobuf/cannedmessages_pb2.pyi new file mode 100644 index 0000000..33c5e2b --- /dev/null +++ b/meshtastic/protobuf/cannedmessages_pb2.pyi @@ -0,0 +1,33 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class CannedMessageModuleConfig(google.protobuf.message.Message): + """ + Canned message module configuration. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MESSAGES_FIELD_NUMBER: builtins.int + messages: builtins.str + """ + Predefined messages for canned message module separated by '|' characters. + """ + def __init__( + self, + *, + messages: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["messages", b"messages"]) -> None: ... + +global___CannedMessageModuleConfig = CannedMessageModuleConfig diff --git a/meshtastic/protobuf/channel_pb2.py b/meshtastic/protobuf/channel_pb2.py new file mode 100644 index 0000000..0980137 --- /dev/null +++ b/meshtastic/protobuf/channel_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/channel.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/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\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=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) diff --git a/meshtastic/protobuf/channel_pb2.pyi b/meshtastic/protobuf/channel_pb2.pyi new file mode 100644 index 0000000..208ed7b --- /dev/null +++ b/meshtastic/protobuf/channel_pb2.pyi @@ -0,0 +1,234 @@ +""" +@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 + +@typing.final +class ChannelSettings(google.protobuf.message.Message): + """ + This information can be encoded as a QRcode/url so that other users can configure + their radio to join the same channel. + A note about how channel names are shown to users: channelname-X + poundsymbol is a prefix used to indicate this is a channel name (idea from @professr). + Where X is a letter from A-Z (base 26) representing a hash of the PSK for this + channel - so that if the user changes anything about the channel (which does + force a new PSK) this letter will also change. Thus preventing user confusion if + two friends try to type in a channel name of "BobsChan" and then can't talk + because their PSKs will be different. + The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26" + This also allows the option of someday if people have the PSK off (zero), the + users COULD type in a channel name and be able to talk. + FIXME: Add description of multi-channel support and how primary vs secondary channels are used. + FIXME: explain how apps use channels for security. + explain how remote settings and remote gpio are managed as an example + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CHANNEL_NUM_FIELD_NUMBER: builtins.int + PSK_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + UPLINK_ENABLED_FIELD_NUMBER: builtins.int + DOWNLINK_ENABLED_FIELD_NUMBER: builtins.int + MODULE_SETTINGS_FIELD_NUMBER: builtins.int + channel_num: builtins.int + """ + Deprecated in favor of LoraConfig.channel_num + """ + psk: builtins.bytes + """ + A simple pre-shared key for now for crypto. + Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256). + A special shorthand is used for 1 byte long psks. + These psks should be treated as only minimally secure, + because they are listed in this source code. + Those bytes are mapped using the following scheme: + `0` = No crypto + `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01} + `2` through 10 = The default channel key, except with 1 through 9 added to the last byte. + Shown to user as simple1 through 10 + """ + name: builtins.str + """ + A SHORT name that will be packed into the URL. + Less than 12 bytes. + Something for end users to call the channel + If this is the empty string it is assumed that this channel + is the special (minimally secure) "Default"channel. + In user interfaces it should be rendered as a local language translation of "X". + For channel_num hashing empty string will be treated as "X". + Where "X" is selected based on the English words listed above for ModemPreset + """ + id: builtins.int + """ + Used to construct a globally unique channel ID. + The full globally unique ID will be: "name.id" where ID is shown as base36. + Assuming that the number of meshtastic users is below 20K (true for a long time) + the chance of this 64 bit random number colliding with anyone else is super low. + And the penalty for collision is low as well, it just means that anyone trying to decrypt channel messages might need to + try multiple candidate channels. + Any time a non wire compatible change is made to a channel, this field should be regenerated. + There are a small number of 'special' globally known (and fairly) insecure standard channels. + Those channels do not have a numeric id included in the settings, but instead it is pulled from + a table of well known IDs. + (see Well Known Channels FIXME) + """ + uplink_enabled: builtins.bool + """ + If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe + """ + downlink_enabled: builtins.bool + """ + If true, messages seen on the internet will be forwarded to the local mesh. + """ + @property + def module_settings(self) -> global___ModuleSettings: + """ + Per-channel module settings. + """ + + def __init__( + self, + *, + channel_num: builtins.int = ..., + psk: builtins.bytes = ..., + name: builtins.str = ..., + id: builtins.int = ..., + uplink_enabled: builtins.bool = ..., + downlink_enabled: builtins.bool = ..., + module_settings: global___ModuleSettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["module_settings", b"module_settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel_num", b"channel_num", "downlink_enabled", b"downlink_enabled", "id", b"id", "module_settings", b"module_settings", "name", b"name", "psk", b"psk", "uplink_enabled", b"uplink_enabled"]) -> None: ... + +global___ChannelSettings = ChannelSettings + +@typing.final +class ModuleSettings(google.protobuf.message.Message): + """ + This message is specifically for modules to store per-channel configuration data. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + POSITION_PRECISION_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_client_muted: builtins.bool + """ + 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_client_muted: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["is_client_muted", b"is_client_muted", "position_precision", b"position_precision"]) -> None: ... + +global___ModuleSettings = ModuleSettings + +@typing.final +class Channel(google.protobuf.message.Message): + """ + A pair of a channel number, mode and the (sharable) settings for that channel + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Role: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Channel._Role.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DISABLED: Channel._Role.ValueType # 0 + """ + This channel is not in use right now + """ + PRIMARY: Channel._Role.ValueType # 1 + """ + This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY + """ + SECONDARY: Channel._Role.ValueType # 2 + """ + Secondary channels are only used for encryption/decryption/authentication purposes. + Their radio settings (freq etc) are ignored, only psk is used. + """ + + class Role(_Role, metaclass=_RoleEnumTypeWrapper): + """ + How this channel is being used (or not). + Note: this field is an enum to give us options for the future. + In particular, someday we might make a 'SCANNING' option. + SCANNING channels could have different frequencies and the radio would + occasionally check that freq to see if anything is being transmitted. + For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow + cross band routing as needed. + If a device has only a single radio (the common case) only one channel can be PRIMARY at a time + (but any number of SECONDARY channels can't be sent received on that common frequency) + """ + + DISABLED: Channel.Role.ValueType # 0 + """ + This channel is not in use right now + """ + PRIMARY: Channel.Role.ValueType # 1 + """ + This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY + """ + SECONDARY: Channel.Role.ValueType # 2 + """ + Secondary channels are only used for encryption/decryption/authentication purposes. + Their radio settings (freq etc) are ignored, only psk is used. + """ + + INDEX_FIELD_NUMBER: builtins.int + SETTINGS_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + index: builtins.int + """ + The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) + (Someday - not currently implemented) An index of -1 could be used to mean "set by name", + in which case the target node will find and set the channel by settings.name. + """ + role: global___Channel.Role.ValueType + """ + TODO: REPLACE + """ + @property + def settings(self) -> global___ChannelSettings: + """ + The new settings, or NULL to disable that channel + """ + + def __init__( + self, + *, + index: builtins.int = ..., + settings: global___ChannelSettings | None = ..., + role: global___Channel.Role.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["settings", b"settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["index", b"index", "role", b"role", "settings", b"settings"]) -> None: ... + +global___Channel = Channel diff --git a/meshtastic/protobuf/clientonly_pb2.py b/meshtastic/protobuf/clientonly_pb2.py new file mode 100644 index 0000000..702bca7 --- /dev/null +++ b/meshtastic/protobuf/clientonly_pb2.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/clientonly.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 meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_localonly__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\"\x9f\x02\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\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configBe\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\023com.geeksville.meshB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_DEVICEPROFILE']._serialized_start=99 + _globals['_DEVICEPROFILE']._serialized_end=386 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/clientonly_pb2.pyi b/meshtastic/protobuf/clientonly_pb2.pyi new file mode 100644 index 0000000..7b3028c --- /dev/null +++ b/meshtastic/protobuf/clientonly_pb2.pyi @@ -0,0 +1,74 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import meshtastic.protobuf.localonly_pb2 +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class DeviceProfile(google.protobuf.message.Message): + """ + This abstraction is used to contain any configuration for provisioning a node on any client. + It is useful for importing and exporting configurations. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LONG_NAME_FIELD_NUMBER: builtins.int + SHORT_NAME_FIELD_NUMBER: builtins.int + CHANNEL_URL_FIELD_NUMBER: builtins.int + CONFIG_FIELD_NUMBER: builtins.int + MODULE_CONFIG_FIELD_NUMBER: builtins.int + long_name: builtins.str + """ + Long name for the node + """ + short_name: builtins.str + """ + Short name of the node + """ + channel_url: builtins.str + """ + The url of the channels from our node + """ + @property + def config(self) -> meshtastic.protobuf.localonly_pb2.LocalConfig: + """ + The Config of the node + """ + + @property + def module_config(self) -> meshtastic.protobuf.localonly_pb2.LocalModuleConfig: + """ + The ModuleConfig of the node + """ + + def __init__( + self, + *, + long_name: builtins.str | None = ..., + short_name: builtins.str | None = ..., + channel_url: builtins.str | None = ..., + config: meshtastic.protobuf.localonly_pb2.LocalConfig | None = ..., + module_config: meshtastic.protobuf.localonly_pb2.LocalModuleConfig | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_channel_url", b"_channel_url"]) -> typing.Literal["channel_url"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_config", b"_config"]) -> typing.Literal["config"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_long_name", b"_long_name"]) -> typing.Literal["long_name"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_module_config", b"_module_config"]) -> typing.Literal["module_config"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_short_name", b"_short_name"]) -> typing.Literal["short_name"] | None: ... + +global___DeviceProfile = DeviceProfile diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py new file mode 100644 index 0000000..c385527 --- /dev/null +++ b/meshtastic/protobuf/config_pb2.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/config.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import 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/config.proto\x12\x13meshtastic.protobuf\"\xed \n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xe2\x05\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"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.config_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014ConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None + _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._serialized_options = b'\030\001' + _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None + _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' + _globals['_CONFIG']._serialized_start=58 + _globals['_CONFIG']._serialized_end=4263 + _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 + _globals['_CONFIG_DEVICECONFIG']._serialized_end=1172 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1089 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1091 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1172 + _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1175 + _globals['_CONFIG_POSITIONCONFIG']._serialized_end=1841 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=1615 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=1786 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1788 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1841 + _globals['_CONFIG_POWERCONFIG']._serialized_start=1844 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2078 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2081 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2481 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2374 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2444 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2446 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2481 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2484 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3222 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=2957 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3034 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3036 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3076 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3078 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3155 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3157 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3222 + _globals['_CONFIG_LORACONFIG']._serialized_start=3225 + _globals['_CONFIG_LORACONFIG']._serialized_end=4059 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=3703 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=3908 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=3911 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4059 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4062 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4244 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4188 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4244 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi new file mode 100644 index 0000000..49d64de --- /dev/null +++ b/meshtastic/protobuf/config_pb2.pyi @@ -0,0 +1,1511 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +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 + +@typing.final +class Config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class DeviceConfig(google.protobuf.message.Message): + """ + Configuration + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Role: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DeviceConfig._Role.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CLIENT: Config.DeviceConfig._Role.ValueType # 0 + """ + Description: App connected or stand alone messaging device. + Technical Details: Default Role + """ + CLIENT_MUTE: Config.DeviceConfig._Role.ValueType # 1 + """ + Description: Device that does not forward packets from other devices. + """ + ROUTER: Config.DeviceConfig._Role.ValueType # 2 + """ + Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list. + Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps. + The wifi radio and the oled screen will be put to sleep. + This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. + """ + ROUTER_CLIENT: Config.DeviceConfig._Role.ValueType # 3 + """ + Description: Combination of both ROUTER and CLIENT. Not for mobile devices. + """ + REPEATER: Config.DeviceConfig._Role.ValueType # 4 + """ + 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. + """ + TRACKER: Config.DeviceConfig._Role.ValueType # 5 + """ + Description: Broadcasts GPS position packets as priority. + Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default. + When used in conjunction with power.is_power_saving = true, nodes will wake up, + send position, and then sleep for position.position_broadcast_secs seconds. + """ + SENSOR: Config.DeviceConfig._Role.ValueType # 6 + """ + Description: Broadcasts telemetry packets as priority. + Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default. + When used in conjunction with power.is_power_saving = true, nodes will wake up, + send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. + """ + TAK: Config.DeviceConfig._Role.ValueType # 7 + """ + Description: Optimized for ATAK system communication and reduces routine broadcasts. + Technical Details: Used for nodes dedicated for connection to an ATAK EUD. + Turns off many of the routine broadcasts to favor CoT packet stream + from the Meshtastic ATAK plugin -> IMeshService -> Node + """ + CLIENT_HIDDEN: Config.DeviceConfig._Role.ValueType # 8 + """ + Description: Device that only broadcasts as needed for stealth or power savings. + Technical Details: Used for nodes that "only speak when spoken to" + Turns all of the routine broadcasts but allows for ad-hoc communication + Still rebroadcasts, but with local only rebroadcast mode (known meshes only) + Can be used for clandestine operation or to dramatically reduce airtime / power consumption + """ + LOST_AND_FOUND: Config.DeviceConfig._Role.ValueType # 9 + """ + Description: Broadcasts location as message to default channel regularly for to assist with device recovery. + Technical Details: Used to automatically send a text message to the mesh + with the current position of the device on a frequent interval: + "I'm lost! Position: lat / long" + """ + TAK_TRACKER: Config.DeviceConfig._Role.ValueType # 10 + """ + Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts. + Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream + and automatic TAK PLI (position location information) broadcasts. + Uses position module configuration to determine TAK PLI broadcast interval. + """ + + class Role(_Role, metaclass=_RoleEnumTypeWrapper): + """ + Defines the device's role on the Mesh network + """ + + CLIENT: Config.DeviceConfig.Role.ValueType # 0 + """ + Description: App connected or stand alone messaging device. + Technical Details: Default Role + """ + CLIENT_MUTE: Config.DeviceConfig.Role.ValueType # 1 + """ + Description: Device that does not forward packets from other devices. + """ + ROUTER: Config.DeviceConfig.Role.ValueType # 2 + """ + Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list. + Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps. + The wifi radio and the oled screen will be put to sleep. + This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. + """ + ROUTER_CLIENT: Config.DeviceConfig.Role.ValueType # 3 + """ + Description: Combination of both ROUTER and CLIENT. Not for mobile devices. + """ + REPEATER: Config.DeviceConfig.Role.ValueType # 4 + """ + 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. + """ + TRACKER: Config.DeviceConfig.Role.ValueType # 5 + """ + Description: Broadcasts GPS position packets as priority. + Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default. + When used in conjunction with power.is_power_saving = true, nodes will wake up, + send position, and then sleep for position.position_broadcast_secs seconds. + """ + SENSOR: Config.DeviceConfig.Role.ValueType # 6 + """ + Description: Broadcasts telemetry packets as priority. + Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default. + When used in conjunction with power.is_power_saving = true, nodes will wake up, + send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. + """ + TAK: Config.DeviceConfig.Role.ValueType # 7 + """ + Description: Optimized for ATAK system communication and reduces routine broadcasts. + Technical Details: Used for nodes dedicated for connection to an ATAK EUD. + Turns off many of the routine broadcasts to favor CoT packet stream + from the Meshtastic ATAK plugin -> IMeshService -> Node + """ + CLIENT_HIDDEN: Config.DeviceConfig.Role.ValueType # 8 + """ + Description: Device that only broadcasts as needed for stealth or power savings. + Technical Details: Used for nodes that "only speak when spoken to" + Turns all of the routine broadcasts but allows for ad-hoc communication + Still rebroadcasts, but with local only rebroadcast mode (known meshes only) + Can be used for clandestine operation or to dramatically reduce airtime / power consumption + """ + LOST_AND_FOUND: Config.DeviceConfig.Role.ValueType # 9 + """ + Description: Broadcasts location as message to default channel regularly for to assist with device recovery. + Technical Details: Used to automatically send a text message to the mesh + with the current position of the device on a frequent interval: + "I'm lost! Position: lat / long" + """ + TAK_TRACKER: Config.DeviceConfig.Role.ValueType # 10 + """ + Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts. + Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream + and automatic TAK PLI (position location information) broadcasts. + Uses position module configuration to determine TAK PLI broadcast interval. + """ + + class _RebroadcastMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RebroadcastModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DeviceConfig._RebroadcastMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ALL: Config.DeviceConfig._RebroadcastMode.ValueType # 0 + """ + Default behavior. + Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. + """ + ALL_SKIP_DECODING: Config.DeviceConfig._RebroadcastMode.ValueType # 1 + """ + Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. + Only available in Repeater role. Setting this on any other roles will result in ALL behavior. + """ + LOCAL_ONLY: Config.DeviceConfig._RebroadcastMode.ValueType # 2 + """ + Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. + Only rebroadcasts message on the nodes local primary / secondary channels. + """ + KNOWN_ONLY: Config.DeviceConfig._RebroadcastMode.ValueType # 3 + """ + Ignores observed messages from foreign meshes like LOCAL_ONLY, + but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) + """ + + class RebroadcastMode(_RebroadcastMode, metaclass=_RebroadcastModeEnumTypeWrapper): + """ + Defines the device's behavior for how messages are rebroadcast + """ + + ALL: Config.DeviceConfig.RebroadcastMode.ValueType # 0 + """ + Default behavior. + Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. + """ + ALL_SKIP_DECODING: Config.DeviceConfig.RebroadcastMode.ValueType # 1 + """ + Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. + Only available in Repeater role. Setting this on any other roles will result in ALL behavior. + """ + LOCAL_ONLY: Config.DeviceConfig.RebroadcastMode.ValueType # 2 + """ + Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. + Only rebroadcasts message on the nodes local primary / secondary channels. + """ + KNOWN_ONLY: Config.DeviceConfig.RebroadcastMode.ValueType # 3 + """ + Ignores observed messages from foreign meshes like LOCAL_ONLY, + but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) + """ + + ROLE_FIELD_NUMBER: builtins.int + SERIAL_ENABLED_FIELD_NUMBER: builtins.int + DEBUG_LOG_ENABLED_FIELD_NUMBER: builtins.int + BUTTON_GPIO_FIELD_NUMBER: builtins.int + BUZZER_GPIO_FIELD_NUMBER: builtins.int + REBROADCAST_MODE_FIELD_NUMBER: builtins.int + NODE_INFO_BROADCAST_SECS_FIELD_NUMBER: builtins.int + DOUBLE_TAP_AS_BUTTON_PRESS_FIELD_NUMBER: builtins.int + IS_MANAGED_FIELD_NUMBER: builtins.int + DISABLE_TRIPLE_CLICK_FIELD_NUMBER: builtins.int + TZDEF_FIELD_NUMBER: builtins.int + LED_HEARTBEAT_DISABLED_FIELD_NUMBER: builtins.int + role: global___Config.DeviceConfig.Role.ValueType + """ + Sets the role of node + """ + serial_enabled: builtins.bool + """ + Disabling this will disable the SerialConsole by not initilizing the StreamAPI + """ + debug_log_enabled: builtins.bool + """ + By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). + Set this to true to leave the debug log outputting even when API is active. + """ + button_gpio: builtins.int + """ + For boards without a hard wired button, this is the pin number that will be used + Boards that have more than one button can swap the function with this one. defaults to BUTTON_PIN if defined. + """ + buzzer_gpio: builtins.int + """ + For boards without a PWM buzzer, this is the pin number that will be used + Defaults to PIN_BUZZER if defined. + """ + rebroadcast_mode: global___Config.DeviceConfig.RebroadcastMode.ValueType + """ + Sets the role of node + """ + node_info_broadcast_secs: builtins.int + """ + Send our nodeinfo this often + Defaults to 900 Seconds (15 minutes) + """ + double_tap_as_button_press: builtins.bool + """ + Treat double tap interrupt on supported accelerometers as a button press if set to true + """ + is_managed: builtins.bool + """ + If true, device is considered to be "managed" by a mesh administrator + Clients should then limit available configuration and administrative options inside the user interface + """ + disable_triple_click: builtins.bool + """ + Disables the triple-press of user button to enable or disable GPS + """ + tzdef: builtins.str + """ + POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. + """ + led_heartbeat_disabled: builtins.bool + """ + If true, disable the default blinking LED (LED_PIN) behavior on the device + """ + def __init__( + self, + *, + role: global___Config.DeviceConfig.Role.ValueType = ..., + serial_enabled: builtins.bool = ..., + debug_log_enabled: builtins.bool = ..., + button_gpio: builtins.int = ..., + buzzer_gpio: builtins.int = ..., + rebroadcast_mode: global___Config.DeviceConfig.RebroadcastMode.ValueType = ..., + node_info_broadcast_secs: builtins.int = ..., + double_tap_as_button_press: builtins.bool = ..., + is_managed: builtins.bool = ..., + disable_triple_click: builtins.bool = ..., + tzdef: builtins.str = ..., + led_heartbeat_disabled: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["button_gpio", b"button_gpio", "buzzer_gpio", b"buzzer_gpio", "debug_log_enabled", b"debug_log_enabled", "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): + """ + Position Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _PositionFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _PositionFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.PositionConfig._PositionFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: Config.PositionConfig._PositionFlags.ValueType # 0 + """ + Required for compilation + """ + ALTITUDE: Config.PositionConfig._PositionFlags.ValueType # 1 + """ + Include an altitude value (if available) + """ + ALTITUDE_MSL: Config.PositionConfig._PositionFlags.ValueType # 2 + """ + Altitude value is MSL + """ + GEOIDAL_SEPARATION: Config.PositionConfig._PositionFlags.ValueType # 4 + """ + Include geoidal separation + """ + DOP: Config.PositionConfig._PositionFlags.ValueType # 8 + """ + Include the DOP value ; PDOP used by default, see below + """ + HVDOP: Config.PositionConfig._PositionFlags.ValueType # 16 + """ + If POS_DOP set, send separate HDOP / VDOP values instead of PDOP + """ + SATINVIEW: Config.PositionConfig._PositionFlags.ValueType # 32 + """ + Include number of "satellites in view" + """ + SEQ_NO: Config.PositionConfig._PositionFlags.ValueType # 64 + """ + Include a sequence number incremented per packet + """ + TIMESTAMP: Config.PositionConfig._PositionFlags.ValueType # 128 + """ + Include positional timestamp (from GPS solution) + """ + HEADING: Config.PositionConfig._PositionFlags.ValueType # 256 + """ + Include positional heading + Intended for use with vehicle not walking speeds + walking speeds are likely to be error prone like the compass + """ + SPEED: Config.PositionConfig._PositionFlags.ValueType # 512 + """ + Include positional speed + Intended for use with vehicle not walking speeds + walking speeds are likely to be error prone like the compass + """ + + class PositionFlags(_PositionFlags, metaclass=_PositionFlagsEnumTypeWrapper): + """ + Bit field of boolean configuration options, indicating which optional + fields to include when assembling POSITION messages. + Longitude, latitude, altitude, speed, heading, and DOP + are always included (also time if GPS-synced) + NOTE: the more fields are included, the larger the message will be - + leading to longer airtime and a higher risk of packet loss + """ + + UNSET: Config.PositionConfig.PositionFlags.ValueType # 0 + """ + Required for compilation + """ + ALTITUDE: Config.PositionConfig.PositionFlags.ValueType # 1 + """ + Include an altitude value (if available) + """ + ALTITUDE_MSL: Config.PositionConfig.PositionFlags.ValueType # 2 + """ + Altitude value is MSL + """ + GEOIDAL_SEPARATION: Config.PositionConfig.PositionFlags.ValueType # 4 + """ + Include geoidal separation + """ + DOP: Config.PositionConfig.PositionFlags.ValueType # 8 + """ + Include the DOP value ; PDOP used by default, see below + """ + HVDOP: Config.PositionConfig.PositionFlags.ValueType # 16 + """ + If POS_DOP set, send separate HDOP / VDOP values instead of PDOP + """ + SATINVIEW: Config.PositionConfig.PositionFlags.ValueType # 32 + """ + Include number of "satellites in view" + """ + SEQ_NO: Config.PositionConfig.PositionFlags.ValueType # 64 + """ + Include a sequence number incremented per packet + """ + TIMESTAMP: Config.PositionConfig.PositionFlags.ValueType # 128 + """ + Include positional timestamp (from GPS solution) + """ + HEADING: Config.PositionConfig.PositionFlags.ValueType # 256 + """ + Include positional heading + Intended for use with vehicle not walking speeds + walking speeds are likely to be error prone like the compass + """ + SPEED: Config.PositionConfig.PositionFlags.ValueType # 512 + """ + Include positional speed + Intended for use with vehicle not walking speeds + walking speeds are likely to be error prone like the compass + """ + + class _GpsMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _GpsModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.PositionConfig._GpsMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DISABLED: Config.PositionConfig._GpsMode.ValueType # 0 + """ + GPS is present but disabled + """ + ENABLED: Config.PositionConfig._GpsMode.ValueType # 1 + """ + GPS is present and enabled + """ + NOT_PRESENT: Config.PositionConfig._GpsMode.ValueType # 2 + """ + GPS is not present on the device + """ + + class GpsMode(_GpsMode, metaclass=_GpsModeEnumTypeWrapper): ... + DISABLED: Config.PositionConfig.GpsMode.ValueType # 0 + """ + GPS is present but disabled + """ + ENABLED: Config.PositionConfig.GpsMode.ValueType # 1 + """ + GPS is present and enabled + """ + NOT_PRESENT: Config.PositionConfig.GpsMode.ValueType # 2 + """ + GPS is not present on the device + """ + + POSITION_BROADCAST_SECS_FIELD_NUMBER: builtins.int + POSITION_BROADCAST_SMART_ENABLED_FIELD_NUMBER: builtins.int + FIXED_POSITION_FIELD_NUMBER: builtins.int + GPS_ENABLED_FIELD_NUMBER: builtins.int + GPS_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + GPS_ATTEMPT_TIME_FIELD_NUMBER: builtins.int + POSITION_FLAGS_FIELD_NUMBER: builtins.int + RX_GPIO_FIELD_NUMBER: builtins.int + TX_GPIO_FIELD_NUMBER: builtins.int + BROADCAST_SMART_MINIMUM_DISTANCE_FIELD_NUMBER: builtins.int + BROADCAST_SMART_MINIMUM_INTERVAL_SECS_FIELD_NUMBER: builtins.int + GPS_EN_GPIO_FIELD_NUMBER: builtins.int + GPS_MODE_FIELD_NUMBER: builtins.int + position_broadcast_secs: builtins.int + """ + We should send our position this often (but only if it has changed significantly) + Defaults to 15 minutes + """ + position_broadcast_smart_enabled: builtins.bool + """ + Adaptive position braoadcast, which is now the default. + """ + fixed_position: builtins.bool + """ + If set, this node is at a fixed position. + We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node. + The lat/lon/alt can be set by an internal GPS or with the help of the app. + """ + gps_enabled: builtins.bool + """ + Is GPS enabled for this node? + """ + gps_update_interval: builtins.int + """ + How often should we try to get GPS position (in seconds) + or zero for the default of once every 30 seconds + or a very large value (maxint) to update only once at boot. + """ + gps_attempt_time: builtins.int + """ + Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time + """ + position_flags: builtins.int + """ + Bit field of boolean configuration options for POSITION messages + (bitwise OR of PositionFlags) + """ + rx_gpio: builtins.int + """ + (Re)define GPS_RX_PIN for your board. + """ + tx_gpio: builtins.int + """ + (Re)define GPS_TX_PIN for your board. + """ + broadcast_smart_minimum_distance: builtins.int + """ + The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled + """ + broadcast_smart_minimum_interval_secs: builtins.int + """ + The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled + """ + gps_en_gpio: builtins.int + """ + (Re)define PIN_GPS_EN for your board. + """ + gps_mode: global___Config.PositionConfig.GpsMode.ValueType + """ + Set where GPS is enabled, disabled, or not present + """ + def __init__( + self, + *, + position_broadcast_secs: builtins.int = ..., + position_broadcast_smart_enabled: builtins.bool = ..., + fixed_position: builtins.bool = ..., + gps_enabled: builtins.bool = ..., + gps_update_interval: builtins.int = ..., + gps_attempt_time: builtins.int = ..., + position_flags: builtins.int = ..., + rx_gpio: builtins.int = ..., + tx_gpio: builtins.int = ..., + broadcast_smart_minimum_distance: builtins.int = ..., + broadcast_smart_minimum_interval_secs: builtins.int = ..., + gps_en_gpio: builtins.int = ..., + gps_mode: global___Config.PositionConfig.GpsMode.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["broadcast_smart_minimum_distance", b"broadcast_smart_minimum_distance", "broadcast_smart_minimum_interval_secs", b"broadcast_smart_minimum_interval_secs", "fixed_position", b"fixed_position", "gps_attempt_time", b"gps_attempt_time", "gps_en_gpio", b"gps_en_gpio", "gps_enabled", b"gps_enabled", "gps_mode", b"gps_mode", "gps_update_interval", b"gps_update_interval", "position_broadcast_secs", b"position_broadcast_secs", "position_broadcast_smart_enabled", b"position_broadcast_smart_enabled", "position_flags", b"position_flags", "rx_gpio", b"rx_gpio", "tx_gpio", b"tx_gpio"]) -> None: ... + + @typing.final + class PowerConfig(google.protobuf.message.Message): + """ + Power Config\\ + See [Power Config](/docs/settings/config/power) for additional power config details. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IS_POWER_SAVING_FIELD_NUMBER: builtins.int + ON_BATTERY_SHUTDOWN_AFTER_SECS_FIELD_NUMBER: builtins.int + ADC_MULTIPLIER_OVERRIDE_FIELD_NUMBER: builtins.int + WAIT_BLUETOOTH_SECS_FIELD_NUMBER: builtins.int + SDS_SECS_FIELD_NUMBER: builtins.int + LS_SECS_FIELD_NUMBER: builtins.int + MIN_WAKE_SECS_FIELD_NUMBER: builtins.int + DEVICE_BATTERY_INA_ADDRESS_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. + 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 + """ + on_battery_shutdown_after_secs: builtins.int + """ + Description: If non-zero, the device will fully power off this many seconds after external power is removed. + """ + adc_multiplier_override: builtins.float + """ + Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) + Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. + https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override + Should be set to floating point value between 2 and 6 + """ + wait_bluetooth_secs: builtins.int + """ + Description: The number of seconds for to wait before turning off BLE in No Bluetooth states + Technical Details: ESP32 Only 0 for default of 1 minute + """ + sds_secs: builtins.int + """ + Super Deep Sleep Seconds + While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep + for this value (default 1 year) or a button press + 0 for default of one year + """ + ls_secs: builtins.int + """ + Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on + Technical Details: ESP32 Only 0 for default of 300 + """ + min_wake_secs: builtins.int + """ + Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value + Technical Details: ESP32 Only 0 for default of 10 seconds + """ + device_battery_ina_address: builtins.int + """ + I2C address of INA_2XX to use for reading device battery voltage + """ + def __init__( + self, + *, + is_power_saving: builtins.bool = ..., + on_battery_shutdown_after_secs: builtins.int = ..., + adc_multiplier_override: builtins.float = ..., + wait_bluetooth_secs: builtins.int = ..., + sds_secs: builtins.int = ..., + ls_secs: builtins.int = ..., + min_wake_secs: builtins.int = ..., + device_battery_ina_address: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... + + @typing.final + class NetworkConfig(google.protobuf.message.Message): + """ + Network Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _AddressMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _AddressModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.NetworkConfig._AddressMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DHCP: Config.NetworkConfig._AddressMode.ValueType # 0 + """ + obtain ip address via DHCP + """ + STATIC: Config.NetworkConfig._AddressMode.ValueType # 1 + """ + use static ip address + """ + + class AddressMode(_AddressMode, metaclass=_AddressModeEnumTypeWrapper): ... + DHCP: Config.NetworkConfig.AddressMode.ValueType # 0 + """ + obtain ip address via DHCP + """ + STATIC: Config.NetworkConfig.AddressMode.ValueType # 1 + """ + use static ip address + """ + + @typing.final + class IpV4Config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IP_FIELD_NUMBER: builtins.int + GATEWAY_FIELD_NUMBER: builtins.int + SUBNET_FIELD_NUMBER: builtins.int + DNS_FIELD_NUMBER: builtins.int + ip: builtins.int + """ + Static IP address + """ + gateway: builtins.int + """ + Static gateway address + """ + subnet: builtins.int + """ + Static subnet mask + """ + dns: builtins.int + """ + Static DNS server address + """ + def __init__( + self, + *, + ip: builtins.int = ..., + gateway: builtins.int = ..., + subnet: builtins.int = ..., + dns: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dns", b"dns", "gateway", b"gateway", "ip", b"ip", "subnet", b"subnet"]) -> None: ... + + WIFI_ENABLED_FIELD_NUMBER: builtins.int + WIFI_SSID_FIELD_NUMBER: builtins.int + WIFI_PSK_FIELD_NUMBER: builtins.int + NTP_SERVER_FIELD_NUMBER: builtins.int + ETH_ENABLED_FIELD_NUMBER: builtins.int + ADDRESS_MODE_FIELD_NUMBER: builtins.int + IPV4_CONFIG_FIELD_NUMBER: builtins.int + RSYSLOG_SERVER_FIELD_NUMBER: builtins.int + wifi_enabled: builtins.bool + """ + Enable WiFi (disables Bluetooth) + """ + wifi_ssid: builtins.str + """ + If set, this node will try to join the specified wifi network and + acquire an address via DHCP + """ + wifi_psk: builtins.str + """ + If set, will be use to authenticate to the named wifi + """ + ntp_server: builtins.str + """ + NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` + """ + eth_enabled: builtins.bool + """ + Enable Ethernet + """ + address_mode: global___Config.NetworkConfig.AddressMode.ValueType + """ + acquire an address via DHCP or assign static + """ + rsyslog_server: builtins.str + """ + rsyslog Server and Port + """ + @property + def ipv4_config(self) -> global___Config.NetworkConfig.IpV4Config: + """ + struct to keep static address + """ + + def __init__( + self, + *, + wifi_enabled: builtins.bool = ..., + wifi_ssid: builtins.str = ..., + wifi_psk: builtins.str = ..., + ntp_server: builtins.str = ..., + eth_enabled: builtins.bool = ..., + address_mode: global___Config.NetworkConfig.AddressMode.ValueType = ..., + ipv4_config: global___Config.NetworkConfig.IpV4Config | None = ..., + rsyslog_server: builtins.str = ..., + ) -> 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", "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): + """ + Display Config + """ + + 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[Config.DisplayConfig._GpsCoordinateFormat.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + 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 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) + V: typing_extensions.TypeAlias = ValueType + + class _DisplayUnitsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._DisplayUnits.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + METRIC: Config.DisplayConfig._DisplayUnits.ValueType # 0 + """ + Metric (Default) + """ + IMPERIAL: Config.DisplayConfig._DisplayUnits.ValueType # 1 + """ + Imperial + """ + + class DisplayUnits(_DisplayUnits, metaclass=_DisplayUnitsEnumTypeWrapper): + """ + Unit display preference + """ + + METRIC: Config.DisplayConfig.DisplayUnits.ValueType # 0 + """ + Metric (Default) + """ + IMPERIAL: Config.DisplayConfig.DisplayUnits.ValueType # 1 + """ + Imperial + """ + + class _OledType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _OledTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._OledType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OLED_AUTO: Config.DisplayConfig._OledType.ValueType # 0 + """ + Default / Auto + """ + OLED_SSD1306: Config.DisplayConfig._OledType.ValueType # 1 + """ + Default / Auto + """ + OLED_SH1106: Config.DisplayConfig._OledType.ValueType # 2 + """ + Default / Auto + """ + OLED_SH1107: Config.DisplayConfig._OledType.ValueType # 3 + """ + Can not be auto detected but set by proto. Used for 128x128 screens + """ + + class OledType(_OledType, metaclass=_OledTypeEnumTypeWrapper): + """ + Override OLED outo detect with this if it fails. + """ + + OLED_AUTO: Config.DisplayConfig.OledType.ValueType # 0 + """ + Default / Auto + """ + OLED_SSD1306: Config.DisplayConfig.OledType.ValueType # 1 + """ + Default / Auto + """ + OLED_SH1106: Config.DisplayConfig.OledType.ValueType # 2 + """ + Default / Auto + """ + OLED_SH1107: Config.DisplayConfig.OledType.ValueType # 3 + """ + Can not be auto detected but set by proto. Used for 128x128 screens + """ + + class _DisplayMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _DisplayModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._DisplayMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DEFAULT: Config.DisplayConfig._DisplayMode.ValueType # 0 + """ + Default. The old style for the 128x64 OLED screen + """ + TWOCOLOR: Config.DisplayConfig._DisplayMode.ValueType # 1 + """ + Rearrange display elements to cater for bicolor OLED displays + """ + INVERTED: Config.DisplayConfig._DisplayMode.ValueType # 2 + """ + Same as TwoColor, but with inverted top bar. Not so good for Epaper displays + """ + COLOR: Config.DisplayConfig._DisplayMode.ValueType # 3 + """ + TFT Full Color Displays (not implemented yet) + """ + + class DisplayMode(_DisplayMode, metaclass=_DisplayModeEnumTypeWrapper): ... + DEFAULT: Config.DisplayConfig.DisplayMode.ValueType # 0 + """ + Default. The old style for the 128x64 OLED screen + """ + TWOCOLOR: Config.DisplayConfig.DisplayMode.ValueType # 1 + """ + Rearrange display elements to cater for bicolor OLED displays + """ + INVERTED: Config.DisplayConfig.DisplayMode.ValueType # 2 + """ + Same as TwoColor, but with inverted top bar. Not so good for Epaper displays + """ + COLOR: Config.DisplayConfig.DisplayMode.ValueType # 3 + """ + TFT Full Color Displays (not implemented yet) + """ + + SCREEN_ON_SECS_FIELD_NUMBER: builtins.int + GPS_FORMAT_FIELD_NUMBER: builtins.int + AUTO_SCREEN_CAROUSEL_SECS_FIELD_NUMBER: builtins.int + COMPASS_NORTH_TOP_FIELD_NUMBER: builtins.int + FLIP_SCREEN_FIELD_NUMBER: builtins.int + UNITS_FIELD_NUMBER: builtins.int + OLED_FIELD_NUMBER: builtins.int + DISPLAYMODE_FIELD_NUMBER: builtins.int + HEADING_BOLD_FIELD_NUMBER: builtins.int + WAKE_ON_TAP_OR_MOTION_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.GpsCoordinateFormat.ValueType + """ + How the GPS coordinates are formatted on the OLED screen. + """ + auto_screen_carousel_secs: builtins.int + """ + Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds. + Potentially useful for devices without user buttons. + """ + compass_north_top: builtins.bool + """ + If this is set, the displayed compass will always point north. if unset, the old behaviour + (top of display is heading direction) is used. + """ + flip_screen: builtins.bool + """ + Flip screen vertically, for cases that mount the screen upside down + """ + units: global___Config.DisplayConfig.DisplayUnits.ValueType + """ + Perferred display units + """ + oled: global___Config.DisplayConfig.OledType.ValueType + """ + Override auto-detect in screen + """ + displaymode: global___Config.DisplayConfig.DisplayMode.ValueType + """ + Display Mode + """ + heading_bold: builtins.bool + """ + Print first line in pseudo-bold? FALSE is original style, TRUE is bold + """ + wake_on_tap_or_motion: builtins.bool + """ + Should we wake the screen up on accelerometer detected motion or tap + """ + def __init__( + self, + *, + screen_on_secs: builtins.int = ..., + gps_format: global___Config.DisplayConfig.GpsCoordinateFormat.ValueType = ..., + auto_screen_carousel_secs: builtins.int = ..., + compass_north_top: builtins.bool = ..., + flip_screen: builtins.bool = ..., + units: global___Config.DisplayConfig.DisplayUnits.ValueType = ..., + oled: global___Config.DisplayConfig.OledType.ValueType = ..., + displaymode: global___Config.DisplayConfig.DisplayMode.ValueType = ..., + heading_bold: builtins.bool = ..., + wake_on_tap_or_motion: 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", "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", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... + + @typing.final + class LoRaConfig(google.protobuf.message.Message): + """ + Lora Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _RegionCode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RegionCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.LoRaConfig._RegionCode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: Config.LoRaConfig._RegionCode.ValueType # 0 + """ + Region is not set + """ + US: Config.LoRaConfig._RegionCode.ValueType # 1 + """ + United States + """ + EU_433: Config.LoRaConfig._RegionCode.ValueType # 2 + """ + European Union 433mhz + """ + EU_868: Config.LoRaConfig._RegionCode.ValueType # 3 + """ + European Union 868mhz + """ + CN: Config.LoRaConfig._RegionCode.ValueType # 4 + """ + China + """ + JP: Config.LoRaConfig._RegionCode.ValueType # 5 + """ + Japan + """ + ANZ: Config.LoRaConfig._RegionCode.ValueType # 6 + """ + Australia / New Zealand + """ + KR: Config.LoRaConfig._RegionCode.ValueType # 7 + """ + Korea + """ + TW: Config.LoRaConfig._RegionCode.ValueType # 8 + """ + Taiwan + """ + RU: Config.LoRaConfig._RegionCode.ValueType # 9 + """ + Russia + """ + IN: Config.LoRaConfig._RegionCode.ValueType # 10 + """ + India + """ + NZ_865: Config.LoRaConfig._RegionCode.ValueType # 11 + """ + New Zealand 865mhz + """ + TH: Config.LoRaConfig._RegionCode.ValueType # 12 + """ + Thailand + """ + LORA_24: Config.LoRaConfig._RegionCode.ValueType # 13 + """ + WLAN Band + """ + UA_433: Config.LoRaConfig._RegionCode.ValueType # 14 + """ + Ukraine 433mhz + """ + UA_868: Config.LoRaConfig._RegionCode.ValueType # 15 + """ + Ukraine 868mhz + """ + MY_433: Config.LoRaConfig._RegionCode.ValueType # 16 + """ + Malaysia 433mhz + """ + MY_919: Config.LoRaConfig._RegionCode.ValueType # 17 + """ + Malaysia 919mhz + """ + SG_923: Config.LoRaConfig._RegionCode.ValueType # 18 + """ + Singapore 923mhz + """ + + class RegionCode(_RegionCode, metaclass=_RegionCodeEnumTypeWrapper): ... + UNSET: Config.LoRaConfig.RegionCode.ValueType # 0 + """ + Region is not set + """ + US: Config.LoRaConfig.RegionCode.ValueType # 1 + """ + United States + """ + EU_433: Config.LoRaConfig.RegionCode.ValueType # 2 + """ + European Union 433mhz + """ + EU_868: Config.LoRaConfig.RegionCode.ValueType # 3 + """ + European Union 868mhz + """ + CN: Config.LoRaConfig.RegionCode.ValueType # 4 + """ + China + """ + JP: Config.LoRaConfig.RegionCode.ValueType # 5 + """ + Japan + """ + ANZ: Config.LoRaConfig.RegionCode.ValueType # 6 + """ + Australia / New Zealand + """ + KR: Config.LoRaConfig.RegionCode.ValueType # 7 + """ + Korea + """ + TW: Config.LoRaConfig.RegionCode.ValueType # 8 + """ + Taiwan + """ + RU: Config.LoRaConfig.RegionCode.ValueType # 9 + """ + Russia + """ + IN: Config.LoRaConfig.RegionCode.ValueType # 10 + """ + India + """ + NZ_865: Config.LoRaConfig.RegionCode.ValueType # 11 + """ + New Zealand 865mhz + """ + TH: Config.LoRaConfig.RegionCode.ValueType # 12 + """ + Thailand + """ + LORA_24: Config.LoRaConfig.RegionCode.ValueType # 13 + """ + WLAN Band + """ + UA_433: Config.LoRaConfig.RegionCode.ValueType # 14 + """ + Ukraine 433mhz + """ + UA_868: Config.LoRaConfig.RegionCode.ValueType # 15 + """ + Ukraine 868mhz + """ + MY_433: Config.LoRaConfig.RegionCode.ValueType # 16 + """ + Malaysia 433mhz + """ + MY_919: Config.LoRaConfig.RegionCode.ValueType # 17 + """ + Malaysia 919mhz + """ + SG_923: Config.LoRaConfig.RegionCode.ValueType # 18 + """ + Singapore 923mhz + """ + + class _ModemPreset: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ModemPresetEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.LoRaConfig._ModemPreset.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LONG_FAST: Config.LoRaConfig._ModemPreset.ValueType # 0 + """ + Long Range - Fast + """ + LONG_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 1 + """ + Long Range - Slow + """ + VERY_LONG_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 2 + """ + Very Long Range - Slow + """ + MEDIUM_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 3 + """ + Medium Range - Slow + """ + MEDIUM_FAST: Config.LoRaConfig._ModemPreset.ValueType # 4 + """ + Medium Range - Fast + """ + SHORT_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 5 + """ + Short Range - Slow + """ + SHORT_FAST: Config.LoRaConfig._ModemPreset.ValueType # 6 + """ + Short Range - Fast + """ + LONG_MODERATE: Config.LoRaConfig._ModemPreset.ValueType # 7 + """ + Long Range - Moderately Fast + """ + + class ModemPreset(_ModemPreset, metaclass=_ModemPresetEnumTypeWrapper): + """ + Standard predefined channel settings + Note: these mappings must match ModemPreset Choice in the device code. + """ + + LONG_FAST: Config.LoRaConfig.ModemPreset.ValueType # 0 + """ + Long Range - Fast + """ + LONG_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 1 + """ + Long Range - Slow + """ + VERY_LONG_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 2 + """ + Very Long Range - Slow + """ + MEDIUM_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 3 + """ + Medium Range - Slow + """ + MEDIUM_FAST: Config.LoRaConfig.ModemPreset.ValueType # 4 + """ + Medium Range - Fast + """ + SHORT_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 5 + """ + Short Range - Slow + """ + SHORT_FAST: Config.LoRaConfig.ModemPreset.ValueType # 6 + """ + Short Range - Fast + """ + LONG_MODERATE: Config.LoRaConfig.ModemPreset.ValueType # 7 + """ + Long Range - Moderately Fast + """ + + USE_PRESET_FIELD_NUMBER: builtins.int + MODEM_PRESET_FIELD_NUMBER: builtins.int + BANDWIDTH_FIELD_NUMBER: builtins.int + SPREAD_FACTOR_FIELD_NUMBER: builtins.int + CODING_RATE_FIELD_NUMBER: builtins.int + FREQUENCY_OFFSET_FIELD_NUMBER: builtins.int + REGION_FIELD_NUMBER: builtins.int + HOP_LIMIT_FIELD_NUMBER: builtins.int + TX_ENABLED_FIELD_NUMBER: builtins.int + TX_POWER_FIELD_NUMBER: builtins.int + CHANNEL_NUM_FIELD_NUMBER: builtins.int + OVERRIDE_DUTY_CYCLE_FIELD_NUMBER: builtins.int + SX126X_RX_BOOSTED_GAIN_FIELD_NUMBER: builtins.int + OVERRIDE_FREQUENCY_FIELD_NUMBER: builtins.int + IGNORE_INCOMING_FIELD_NUMBER: builtins.int + IGNORE_MQTT_FIELD_NUMBER: builtins.int + use_preset: builtins.bool + """ + When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` + will be taked from their respective manually defined fields + """ + modem_preset: global___Config.LoRaConfig.ModemPreset.ValueType + """ + Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. + As a heuristic: If bandwidth is specified, do not use modem_config. + Because protobufs take ZERO space when the value is zero this works out nicely. + This value is replaced by bandwidth/spread_factor/coding_rate. + If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. + """ + bandwidth: builtins.int + """ + Bandwidth in MHz + Certain bandwidth numbers are 'special' and will be converted to the + appropriate floating point value: 31 -> 31.25MHz + """ + spread_factor: builtins.int + """ + A number from 7 to 12. + Indicates number of chirps per symbol as 1< 7 results in the default + """ + tx_enabled: builtins.bool + """ + Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests. + Defaults to false + """ + tx_power: builtins.int + """ + If zero, then use default max legal continuous power (ie. something that won't + burn out the radio hardware) + In most cases you should use zero here. + Units are in dBm. + """ + channel_num: builtins.int + """ + This controls the actual hardware frequency the radio transmits on. + Most users should never need to be exposed to this field/concept. + A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region). + If ZERO then the rule is "use the old channel name hash based + algorithm to derive the channel number") + If using the hash algorithm the channel number will be: hash(channel_name) % + NUM_CHANNELS (Where num channels depends on the regulatory region). + """ + override_duty_cycle: builtins.bool + """ + If true, duty cycle limits will be exceeded and thus you're possibly not following + the local regulations if you're not a HAM. + Has no effect if the duty cycle of the used region is 100%. + """ + sx126x_rx_boosted_gain: builtins.bool + """ + If true, sets RX boosted gain mode on SX126X based radios + """ + override_frequency: builtins.float + """ + This parameter is for advanced users and licensed HAM radio operators. + Ignore Channel Calculation and use this frequency instead. The frequency_offset + will still be applied. This will allow you to use out-of-band frequencies. + Please respect your local laws and regulations. If you are a HAM, make sure you + enable HAM mode and turn off encryption. + """ + ignore_mqtt: builtins.bool + """ + If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. + """ + @property + def ignore_incoming(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """ + For testing it is useful sometimes to force a node to never listen to + particular other nodes (simulating radio out of range). All nodenums listed + in ignore_incoming will have packets they send dropped on receive (by router.cpp) + """ + + def __init__( + self, + *, + use_preset: builtins.bool = ..., + modem_preset: global___Config.LoRaConfig.ModemPreset.ValueType = ..., + bandwidth: builtins.int = ..., + spread_factor: builtins.int = ..., + coding_rate: builtins.int = ..., + frequency_offset: builtins.float = ..., + region: global___Config.LoRaConfig.RegionCode.ValueType = ..., + hop_limit: builtins.int = ..., + tx_enabled: builtins.bool = ..., + tx_power: builtins.int = ..., + channel_num: builtins.int = ..., + override_duty_cycle: builtins.bool = ..., + sx126x_rx_boosted_gain: builtins.bool = ..., + override_frequency: builtins.float = ..., + ignore_incoming: collections.abc.Iterable[builtins.int] | None = ..., + ignore_mqtt: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... + + @typing.final + class BluetoothConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _PairingMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _PairingModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.BluetoothConfig._PairingMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RANDOM_PIN: Config.BluetoothConfig._PairingMode.ValueType # 0 + """ + Device generates a random PIN that will be shown on the screen of the device for pairing + """ + FIXED_PIN: Config.BluetoothConfig._PairingMode.ValueType # 1 + """ + Device requires a specified fixed PIN for pairing + """ + NO_PIN: Config.BluetoothConfig._PairingMode.ValueType # 2 + """ + Device requires no PIN for pairing + """ + + class PairingMode(_PairingMode, metaclass=_PairingModeEnumTypeWrapper): ... + RANDOM_PIN: Config.BluetoothConfig.PairingMode.ValueType # 0 + """ + Device generates a random PIN that will be shown on the screen of the device for pairing + """ + FIXED_PIN: Config.BluetoothConfig.PairingMode.ValueType # 1 + """ + Device requires a specified fixed PIN for pairing + """ + NO_PIN: Config.BluetoothConfig.PairingMode.ValueType # 2 + """ + Device requires no PIN for pairing + """ + + ENABLED_FIELD_NUMBER: builtins.int + MODE_FIELD_NUMBER: builtins.int + FIXED_PIN_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Enable Bluetooth on the device + """ + mode: global___Config.BluetoothConfig.PairingMode.ValueType + """ + Determines the pairing strategy for the device + """ + fixed_pin: builtins.int + """ + Specified PIN for PairingMode.FixedPin + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + mode: global___Config.BluetoothConfig.PairingMode.ValueType = ..., + fixed_pin: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... + + DEVICE_FIELD_NUMBER: builtins.int + POSITION_FIELD_NUMBER: builtins.int + POWER_FIELD_NUMBER: builtins.int + NETWORK_FIELD_NUMBER: builtins.int + DISPLAY_FIELD_NUMBER: builtins.int + LORA_FIELD_NUMBER: builtins.int + BLUETOOTH_FIELD_NUMBER: builtins.int + @property + def device(self) -> global___Config.DeviceConfig: ... + @property + def position(self) -> global___Config.PositionConfig: ... + @property + def power(self) -> global___Config.PowerConfig: ... + @property + def network(self) -> global___Config.NetworkConfig: ... + @property + def display(self) -> global___Config.DisplayConfig: ... + @property + def lora(self) -> global___Config.LoRaConfig: ... + @property + def bluetooth(self) -> global___Config.BluetoothConfig: ... + def __init__( + self, + *, + device: global___Config.DeviceConfig | None = ..., + position: global___Config.PositionConfig | None = ..., + power: global___Config.PowerConfig | None = ..., + network: global___Config.NetworkConfig | None = ..., + display: global___Config.DisplayConfig | None = ..., + lora: global___Config.LoRaConfig | None = ..., + bluetooth: global___Config.BluetoothConfig | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["device", "position", "power", "network", "display", "lora", "bluetooth"] | None: ... + +global___Config = Config diff --git a/meshtastic/protobuf/connection_status_pb2.py b/meshtastic/protobuf/connection_status_pb2.py new file mode 100644 index 0000000..f5dfa33 --- /dev/null +++ b/meshtastic/protobuf/connection_status_pb2.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/connection_status.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import 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/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\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 + _globals['_WIFICONNECTIONSTATUS']._serialized_end=524 + _globals['_ETHERNETCONNECTIONSTATUS']._serialized_start=526 + _globals['_ETHERNETCONNECTIONSTATUS']._serialized_end=614 + _globals['_NETWORKCONNECTIONSTATUS']._serialized_start=616 + _globals['_NETWORKCONNECTIONSTATUS']._serialized_end=739 + _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_start=741 + _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_end=817 + _globals['_SERIALCONNECTIONSTATUS']._serialized_start=819 + _globals['_SERIALCONNECTIONSTATUS']._serialized_end=879 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/connection_status_pb2.pyi b/meshtastic/protobuf/connection_status_pb2.pyi new file mode 100644 index 0000000..7b69140 --- /dev/null +++ b/meshtastic/protobuf/connection_status_pb2.pyi @@ -0,0 +1,228 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class DeviceConnectionStatus(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + WIFI_FIELD_NUMBER: builtins.int + ETHERNET_FIELD_NUMBER: builtins.int + BLUETOOTH_FIELD_NUMBER: builtins.int + SERIAL_FIELD_NUMBER: builtins.int + @property + def wifi(self) -> global___WifiConnectionStatus: + """ + WiFi Status + """ + + @property + def ethernet(self) -> global___EthernetConnectionStatus: + """ + WiFi Status + """ + + @property + def bluetooth(self) -> global___BluetoothConnectionStatus: + """ + Bluetooth Status + """ + + @property + def serial(self) -> global___SerialConnectionStatus: + """ + Serial Status + """ + + def __init__( + self, + *, + wifi: global___WifiConnectionStatus | None = ..., + ethernet: global___EthernetConnectionStatus | None = ..., + bluetooth: global___BluetoothConnectionStatus | None = ..., + serial: global___SerialConnectionStatus | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_bluetooth", b"_bluetooth"]) -> typing.Literal["bluetooth"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ethernet", b"_ethernet"]) -> typing.Literal["ethernet"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_serial", b"_serial"]) -> typing.Literal["serial"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_wifi", b"_wifi"]) -> typing.Literal["wifi"] | None: ... + +global___DeviceConnectionStatus = DeviceConnectionStatus + +@typing.final +class WifiConnectionStatus(google.protobuf.message.Message): + """ + WiFi connection status + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STATUS_FIELD_NUMBER: builtins.int + SSID_FIELD_NUMBER: builtins.int + RSSI_FIELD_NUMBER: builtins.int + ssid: builtins.str + """ + WiFi access point SSID + """ + rssi: builtins.int + """ + RSSI of wireless connection + """ + @property + def status(self) -> global___NetworkConnectionStatus: + """ + Connection status + """ + + def __init__( + self, + *, + status: global___NetworkConnectionStatus | None = ..., + ssid: builtins.str = ..., + rssi: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["rssi", b"rssi", "ssid", b"ssid", "status", b"status"]) -> None: ... + +global___WifiConnectionStatus = WifiConnectionStatus + +@typing.final +class EthernetConnectionStatus(google.protobuf.message.Message): + """ + Ethernet connection status + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STATUS_FIELD_NUMBER: builtins.int + @property + def status(self) -> global___NetworkConnectionStatus: + """ + Connection status + """ + + def __init__( + self, + *, + status: global___NetworkConnectionStatus | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["status", b"status"]) -> None: ... + +global___EthernetConnectionStatus = EthernetConnectionStatus + +@typing.final +class NetworkConnectionStatus(google.protobuf.message.Message): + """ + Ethernet or WiFi connection status + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IP_ADDRESS_FIELD_NUMBER: builtins.int + IS_CONNECTED_FIELD_NUMBER: builtins.int + IS_MQTT_CONNECTED_FIELD_NUMBER: builtins.int + IS_SYSLOG_CONNECTED_FIELD_NUMBER: builtins.int + ip_address: builtins.int + """ + IP address of device + """ + is_connected: builtins.bool + """ + Whether the device has an active connection or not + """ + is_mqtt_connected: builtins.bool + """ + Whether the device has an active connection to an MQTT broker or not + """ + is_syslog_connected: builtins.bool + """ + Whether the device is actively remote syslogging or not + """ + def __init__( + self, + *, + ip_address: builtins.int = ..., + is_connected: builtins.bool = ..., + is_mqtt_connected: builtins.bool = ..., + is_syslog_connected: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ip_address", b"ip_address", "is_connected", b"is_connected", "is_mqtt_connected", b"is_mqtt_connected", "is_syslog_connected", b"is_syslog_connected"]) -> None: ... + +global___NetworkConnectionStatus = NetworkConnectionStatus + +@typing.final +class BluetoothConnectionStatus(google.protobuf.message.Message): + """ + Bluetooth connection status + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PIN_FIELD_NUMBER: builtins.int + RSSI_FIELD_NUMBER: builtins.int + IS_CONNECTED_FIELD_NUMBER: builtins.int + pin: builtins.int + """ + The pairing PIN for bluetooth + """ + rssi: builtins.int + """ + RSSI of bluetooth connection + """ + is_connected: builtins.bool + """ + Whether the device has an active connection or not + """ + def __init__( + self, + *, + pin: builtins.int = ..., + rssi: builtins.int = ..., + is_connected: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["is_connected", b"is_connected", "pin", b"pin", "rssi", b"rssi"]) -> None: ... + +global___BluetoothConnectionStatus = BluetoothConnectionStatus + +@typing.final +class SerialConnectionStatus(google.protobuf.message.Message): + """ + Serial connection status + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BAUD_FIELD_NUMBER: builtins.int + IS_CONNECTED_FIELD_NUMBER: builtins.int + baud: builtins.int + """ + Serial baud rate + """ + is_connected: builtins.bool + """ + Whether the device has an active connection or not + """ + def __init__( + self, + *, + baud: builtins.int = ..., + is_connected: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["baud", b"baud", "is_connected", b"is_connected"]) -> None: ... + +global___SerialConnectionStatus = SerialConnectionStatus diff --git a/meshtastic/protobuf/deviceonly_pb2.py b/meshtastic/protobuf/deviceonly_pb2.py new file mode 100644 index 0000000..9e7f9d4 --- /dev/null +++ b/meshtastic/protobuf/deviceonly_pb2.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/deviceonly.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 meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__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 module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 +from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__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/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a#meshtastic/protobuf/telemetry.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\"\xa1\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\x82\x04\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\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\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\x12\x63\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"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\"\xb2\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x32\n\x08oem_font\x18\x04 \x01(\x0e\x32 .meshtastic.protobuf.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12:\n\x10oem_local_config\x18\x07 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12G\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\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\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010' + _DEVICESTATE.fields_by_name['no_save']._options = None + _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' + _DEVICESTATE.fields_by_name['node_db_lite']._options = None + _DEVICESTATE.fields_by_name['node_db_lite']._serialized_options = b'\222?\'\222\001$std::vector' + _globals['_SCREENFONTS']._serialized_start=1611 + _globals['_SCREENFONTS']._serialized_end=1673 + _globals['_POSITIONLITE']._serialized_start=258 + _globals['_POSITIONLITE']._serialized_end=411 + _globals['_NODEINFOLITE']._serialized_start=414 + _globals['_NODEINFOLITE']._serialized_end=703 + _globals['_DEVICESTATE']._serialized_start=706 + _globals['_DEVICESTATE']._serialized_end=1220 + _globals['_CHANNELFILE']._serialized_start=1222 + _globals['_CHANNELFILE']._serialized_end=1300 + _globals['_OEMSTORE']._serialized_start=1303 + _globals['_OEMSTORE']._serialized_end=1609 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/deviceonly_pb2.pyi b/meshtastic/protobuf/deviceonly_pb2.pyi new file mode 100644 index 0000000..c0ca537 --- /dev/null +++ b/meshtastic/protobuf/deviceonly_pb2.pyi @@ -0,0 +1,400 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import meshtastic.protobuf.channel_pb2 +import meshtastic.protobuf.localonly_pb2 +import meshtastic.protobuf.mesh_pb2 +import meshtastic.protobuf.telemetry_pb2 +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 _ScreenFonts: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ScreenFontsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ScreenFonts.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + FONT_SMALL: _ScreenFonts.ValueType # 0 + """ + TODO: REPLACE + """ + FONT_MEDIUM: _ScreenFonts.ValueType # 1 + """ + TODO: REPLACE + """ + FONT_LARGE: _ScreenFonts.ValueType # 2 + """ + TODO: REPLACE + """ + +class ScreenFonts(_ScreenFonts, metaclass=_ScreenFontsEnumTypeWrapper): + """ + Font sizes for the device screen + """ + +FONT_SMALL: ScreenFonts.ValueType # 0 +""" +TODO: REPLACE +""" +FONT_MEDIUM: ScreenFonts.ValueType # 1 +""" +TODO: REPLACE +""" +FONT_LARGE: ScreenFonts.ValueType # 2 +""" +TODO: REPLACE +""" +global___ScreenFonts = ScreenFonts + +@typing.final +class PositionLite(google.protobuf.message.Message): + """ + Position with static location information only for NodeDBLite + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + ALTITUDE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LOCATION_SOURCE_FIELD_NUMBER: builtins.int + latitude_i: builtins.int + """ + The new preferred location encoding, multiply by 1e-7 to get degrees + in floating point + """ + longitude_i: builtins.int + """ + TODO: REPLACE + """ + altitude: builtins.int + """ + In meters above MSL (but see issue #359) + """ + time: builtins.int + """ + This is usually not sent over the mesh (to save space), but it is sent + from the phone so that the local device can set its RTC If it is sent over + the mesh (because there are devices on the mesh without GPS), it will only + be sent by devices which has a hardware GPS clock. + seconds since 1970 + """ + location_source: meshtastic.protobuf.mesh_pb2.Position.LocSource.ValueType + """ + TODO: REPLACE + """ + def __init__( + self, + *, + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + altitude: builtins.int = ..., + time: builtins.int = ..., + location_source: meshtastic.protobuf.mesh_pb2.Position.LocSource.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "time", b"time"]) -> None: ... + +global___PositionLite = PositionLite + +@typing.final +class NodeInfoLite(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NUM_FIELD_NUMBER: builtins.int + USER_FIELD_NUMBER: builtins.int + POSITION_FIELD_NUMBER: builtins.int + SNR_FIELD_NUMBER: builtins.int + LAST_HEARD_FIELD_NUMBER: builtins.int + DEVICE_METRICS_FIELD_NUMBER: builtins.int + CHANNEL_FIELD_NUMBER: builtins.int + VIA_MQTT_FIELD_NUMBER: builtins.int + HOPS_AWAY_FIELD_NUMBER: builtins.int + IS_FAVORITE_FIELD_NUMBER: builtins.int + num: builtins.int + """ + The node number + """ + snr: builtins.float + """ + Returns the Signal-to-noise ratio (SNR) of the last received message, + as measured by the receiver. Return SNR of the last received message in dB + """ + last_heard: builtins.int + """ + Set to indicate the last time we received a packet from this node + """ + channel: builtins.int + """ + local channel index we heard that node on. Only populated if its not the default channel. + """ + via_mqtt: builtins.bool + """ + True if we witnessed the node over MQTT instead of LoRA transport + """ + hops_away: builtins.int + """ + Number of hops away from us this node is (0 if adjacent) + """ + is_favorite: builtins.bool + """ + True if node is in our favorites list + Persists between NodeDB internal clean ups + """ + @property + def user(self) -> meshtastic.protobuf.mesh_pb2.User: + """ + The user info for this node + """ + + @property + def position(self) -> global___PositionLite: + """ + This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. + Position.time now indicates the last time we received a POSITION from that node. + """ + + @property + def device_metrics(self) -> meshtastic.protobuf.telemetry_pb2.DeviceMetrics: + """ + The latest device metrics for the node. + """ + + def __init__( + self, + *, + num: builtins.int = ..., + user: meshtastic.protobuf.mesh_pb2.User | None = ..., + position: global___PositionLite | None = ..., + snr: builtins.float = ..., + last_heard: builtins.int = ..., + device_metrics: meshtastic.protobuf.telemetry_pb2.DeviceMetrics | None = ..., + channel: builtins.int = ..., + via_mqtt: builtins.bool = ..., + hops_away: builtins.int = ..., + is_favorite: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ... + +global___NodeInfoLite = NodeInfoLite + +@typing.final +class DeviceState(google.protobuf.message.Message): + """ + This message is never sent over the wire, but it is used for serializing DB + state to flash in the device code + FIXME, since we write this each time we enter deep sleep (and have infinite + flash) it would be better to use some sort of append only data structure for + the receive queue and use the preferences store for the other stuff + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MY_NODE_FIELD_NUMBER: builtins.int + OWNER_FIELD_NUMBER: builtins.int + RECEIVE_QUEUE_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + RX_TEXT_MESSAGE_FIELD_NUMBER: builtins.int + NO_SAVE_FIELD_NUMBER: builtins.int + DID_GPS_RESET_FIELD_NUMBER: builtins.int + RX_WAYPOINT_FIELD_NUMBER: builtins.int + NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: builtins.int + NODE_DB_LITE_FIELD_NUMBER: builtins.int + version: builtins.int + """ + A version integer used to invalidate old save files when we make + incompatible changes This integer is set at build time and is private to + NodeDB.cpp in the device code. + """ + no_save: builtins.bool + """ + Used only during development. + Indicates developer is testing and changes should never be saved to flash. + Deprecated in 2.3.1 + """ + did_gps_reset: builtins.bool + """ + Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. + """ + @property + def my_node(self) -> meshtastic.protobuf.mesh_pb2.MyNodeInfo: + """ + Read only settings/info about this node + """ + + @property + def owner(self) -> meshtastic.protobuf.mesh_pb2.User: + """ + My owner info + """ + + @property + def receive_queue(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.mesh_pb2.MeshPacket]: + """ + Received packets saved for delivery to the phone + """ + + @property + def rx_text_message(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket: + """ + We keep the last received text message (only) stored in the device flash, + so we can show it on the screen. + Might be null + """ + + @property + def rx_waypoint(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket: + """ + We keep the last received waypoint stored in the device flash, + so we can show it on the screen. + Might be null + """ + + @property + def node_remote_hardware_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin]: + """ + The mesh's nodes with their available gpio pins for RemoteHardware module + """ + + @property + def node_db_lite(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NodeInfoLite]: + """ + New lite version of NodeDB to decrease memory footprint + """ + + def __init__( + self, + *, + my_node: meshtastic.protobuf.mesh_pb2.MyNodeInfo | None = ..., + owner: meshtastic.protobuf.mesh_pb2.User | None = ..., + receive_queue: collections.abc.Iterable[meshtastic.protobuf.mesh_pb2.MeshPacket] | None = ..., + version: builtins.int = ..., + rx_text_message: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ..., + no_save: builtins.bool = ..., + did_gps_reset: builtins.bool = ..., + rx_waypoint: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ..., + node_remote_hardware_pins: collections.abc.Iterable[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin] | None = ..., + node_db_lite: collections.abc.Iterable[global___NodeInfoLite] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["my_node", b"my_node", "owner", b"owner", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["did_gps_reset", b"did_gps_reset", "my_node", b"my_node", "no_save", b"no_save", "node_db_lite", b"node_db_lite", "node_remote_hardware_pins", b"node_remote_hardware_pins", "owner", b"owner", "receive_queue", b"receive_queue", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint", "version", b"version"]) -> None: ... + +global___DeviceState = DeviceState + +@typing.final +class ChannelFile(google.protobuf.message.Message): + """ + The on-disk saved channels + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CHANNELS_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + version: builtins.int + """ + A version integer used to invalidate old save files when we make + incompatible changes This integer is set at build time and is private to + NodeDB.cpp in the device code. + """ + @property + def channels(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.channel_pb2.Channel]: + """ + The channels our node knows about + """ + + def __init__( + self, + *, + channels: collections.abc.Iterable[meshtastic.protobuf.channel_pb2.Channel] | None = ..., + version: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["channels", b"channels", "version", b"version"]) -> None: ... + +global___ChannelFile = ChannelFile + +@typing.final +class OEMStore(google.protobuf.message.Message): + """ + This can be used for customizing the firmware distribution. If populated, + show a secondary bootup screen with custom logo and text for 2.5 seconds. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + OEM_ICON_WIDTH_FIELD_NUMBER: builtins.int + OEM_ICON_HEIGHT_FIELD_NUMBER: builtins.int + OEM_ICON_BITS_FIELD_NUMBER: builtins.int + OEM_FONT_FIELD_NUMBER: builtins.int + OEM_TEXT_FIELD_NUMBER: builtins.int + OEM_AES_KEY_FIELD_NUMBER: builtins.int + OEM_LOCAL_CONFIG_FIELD_NUMBER: builtins.int + OEM_LOCAL_MODULE_CONFIG_FIELD_NUMBER: builtins.int + oem_icon_width: builtins.int + """ + The Logo width in Px + """ + oem_icon_height: builtins.int + """ + The Logo height in Px + """ + oem_icon_bits: builtins.bytes + """ + The Logo in XBM bytechar format + """ + oem_font: global___ScreenFonts.ValueType + """ + Use this font for the OEM text. + """ + oem_text: builtins.str + """ + Use this font for the OEM text. + """ + oem_aes_key: builtins.bytes + """ + The default device encryption key, 16 or 32 byte + """ + @property + def oem_local_config(self) -> meshtastic.protobuf.localonly_pb2.LocalConfig: + """ + A Preset LocalConfig to apply during factory reset + """ + + @property + def oem_local_module_config(self) -> meshtastic.protobuf.localonly_pb2.LocalModuleConfig: + """ + A Preset LocalModuleConfig to apply during factory reset + """ + + def __init__( + self, + *, + oem_icon_width: builtins.int = ..., + oem_icon_height: builtins.int = ..., + oem_icon_bits: builtins.bytes = ..., + oem_font: global___ScreenFonts.ValueType = ..., + oem_text: builtins.str = ..., + oem_aes_key: builtins.bytes = ..., + oem_local_config: meshtastic.protobuf.localonly_pb2.LocalConfig | None = ..., + oem_local_module_config: meshtastic.protobuf.localonly_pb2.LocalModuleConfig | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["oem_local_config", b"oem_local_config", "oem_local_module_config", b"oem_local_module_config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["oem_aes_key", b"oem_aes_key", "oem_font", b"oem_font", "oem_icon_bits", b"oem_icon_bits", "oem_icon_height", b"oem_icon_height", "oem_icon_width", b"oem_icon_width", "oem_local_config", b"oem_local_config", "oem_local_module_config", b"oem_local_module_config", "oem_text", b"oem_text"]) -> None: ... + +global___OEMStore = OEMStore diff --git a/meshtastic/protobuf/localonly_pb2.py b/meshtastic/protobuf/localonly_pb2.py new file mode 100644 index 0000000..f4e4d71 --- /dev/null +++ b/meshtastic/protobuf/localonly_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/localonly.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2 +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\"\xbc\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\"\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\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=580 + _globals['_LOCALMODULECONFIG']._serialized_start=583 + _globals['_LOCALMODULECONFIG']._serialized_end=1591 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/localonly_pb2.pyi b/meshtastic/protobuf/localonly_pb2.pyi new file mode 100644 index 0000000..ca62f18 --- /dev/null +++ b/meshtastic/protobuf/localonly_pb2.pyi @@ -0,0 +1,220 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import meshtastic.protobuf.config_pb2 +import meshtastic.protobuf.module_config_pb2 +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class LocalConfig(google.protobuf.message.Message): + """ + Protobuf structures common to apponly.proto and deviceonly.proto + This is never sent over the wire, only for local use + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DEVICE_FIELD_NUMBER: builtins.int + POSITION_FIELD_NUMBER: builtins.int + POWER_FIELD_NUMBER: builtins.int + NETWORK_FIELD_NUMBER: builtins.int + DISPLAY_FIELD_NUMBER: builtins.int + LORA_FIELD_NUMBER: builtins.int + BLUETOOTH_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + version: builtins.int + """ + A version integer used to invalidate old save files when we make + incompatible changes This integer is set at build time and is private to + NodeDB.cpp in the device code. + """ + @property + def device(self) -> meshtastic.protobuf.config_pb2.Config.DeviceConfig: + """ + The part of the config that is specific to the Device + """ + + @property + def position(self) -> meshtastic.protobuf.config_pb2.Config.PositionConfig: + """ + The part of the config that is specific to the GPS Position + """ + + @property + def power(self) -> meshtastic.protobuf.config_pb2.Config.PowerConfig: + """ + The part of the config that is specific to the Power settings + """ + + @property + def network(self) -> meshtastic.protobuf.config_pb2.Config.NetworkConfig: + """ + The part of the config that is specific to the Wifi Settings + """ + + @property + def display(self) -> meshtastic.protobuf.config_pb2.Config.DisplayConfig: + """ + The part of the config that is specific to the Display + """ + + @property + def lora(self) -> meshtastic.protobuf.config_pb2.Config.LoRaConfig: + """ + The part of the config that is specific to the Lora Radio + """ + + @property + def bluetooth(self) -> meshtastic.protobuf.config_pb2.Config.BluetoothConfig: + """ + The part of the config that is specific to the Bluetooth settings + """ + + def __init__( + self, + *, + device: meshtastic.protobuf.config_pb2.Config.DeviceConfig | None = ..., + position: meshtastic.protobuf.config_pb2.Config.PositionConfig | None = ..., + power: meshtastic.protobuf.config_pb2.Config.PowerConfig | None = ..., + network: meshtastic.protobuf.config_pb2.Config.NetworkConfig | None = ..., + display: meshtastic.protobuf.config_pb2.Config.DisplayConfig | None = ..., + lora: meshtastic.protobuf.config_pb2.Config.LoRaConfig | None = ..., + bluetooth: meshtastic.protobuf.config_pb2.Config.BluetoothConfig | None = ..., + version: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "version", b"version"]) -> None: ... + +global___LocalConfig = LocalConfig + +@typing.final +class LocalModuleConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MQTT_FIELD_NUMBER: builtins.int + SERIAL_FIELD_NUMBER: builtins.int + EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int + STORE_FORWARD_FIELD_NUMBER: builtins.int + RANGE_TEST_FIELD_NUMBER: builtins.int + TELEMETRY_FIELD_NUMBER: builtins.int + CANNED_MESSAGE_FIELD_NUMBER: builtins.int + AUDIO_FIELD_NUMBER: builtins.int + REMOTE_HARDWARE_FIELD_NUMBER: builtins.int + NEIGHBOR_INFO_FIELD_NUMBER: builtins.int + AMBIENT_LIGHTING_FIELD_NUMBER: builtins.int + DETECTION_SENSOR_FIELD_NUMBER: builtins.int + PAXCOUNTER_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + version: builtins.int + """ + A version integer used to invalidate old save files when we make + incompatible changes This integer is set at build time and is private to + NodeDB.cpp in the device code. + """ + @property + def mqtt(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.MQTTConfig: + """ + The part of the config that is specific to the MQTT module + """ + + @property + def serial(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.SerialConfig: + """ + The part of the config that is specific to the Serial module + """ + + @property + def external_notification(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.ExternalNotificationConfig: + """ + The part of the config that is specific to the ExternalNotification module + """ + + @property + def store_forward(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.StoreForwardConfig: + """ + The part of the config that is specific to the Store & Forward module + """ + + @property + def range_test(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.RangeTestConfig: + """ + The part of the config that is specific to the RangeTest module + """ + + @property + def telemetry(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.TelemetryConfig: + """ + The part of the config that is specific to the Telemetry module + """ + + @property + def canned_message(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.CannedMessageConfig: + """ + The part of the config that is specific to the Canned Message module + """ + + @property + def audio(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.AudioConfig: + """ + The part of the config that is specific to the Audio module + """ + + @property + def remote_hardware(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.RemoteHardwareConfig: + """ + The part of the config that is specific to the Remote Hardware module + """ + + @property + def neighbor_info(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.NeighborInfoConfig: + """ + The part of the config that is specific to the Neighbor Info module + """ + + @property + def ambient_lighting(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.AmbientLightingConfig: + """ + The part of the config that is specific to the Ambient Lighting module + """ + + @property + def detection_sensor(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig: + """ + The part of the config that is specific to the Detection Sensor module + """ + + @property + def paxcounter(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig: + """ + Paxcounter Config + """ + + def __init__( + self, + *, + mqtt: meshtastic.protobuf.module_config_pb2.ModuleConfig.MQTTConfig | None = ..., + serial: meshtastic.protobuf.module_config_pb2.ModuleConfig.SerialConfig | None = ..., + external_notification: meshtastic.protobuf.module_config_pb2.ModuleConfig.ExternalNotificationConfig | None = ..., + store_forward: meshtastic.protobuf.module_config_pb2.ModuleConfig.StoreForwardConfig | None = ..., + range_test: meshtastic.protobuf.module_config_pb2.ModuleConfig.RangeTestConfig | None = ..., + telemetry: meshtastic.protobuf.module_config_pb2.ModuleConfig.TelemetryConfig | None = ..., + canned_message: meshtastic.protobuf.module_config_pb2.ModuleConfig.CannedMessageConfig | None = ..., + audio: meshtastic.protobuf.module_config_pb2.ModuleConfig.AudioConfig | None = ..., + remote_hardware: meshtastic.protobuf.module_config_pb2.ModuleConfig.RemoteHardwareConfig | None = ..., + neighbor_info: meshtastic.protobuf.module_config_pb2.ModuleConfig.NeighborInfoConfig | None = ..., + ambient_lighting: meshtastic.protobuf.module_config_pb2.ModuleConfig.AmbientLightingConfig | None = ..., + detection_sensor: meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig | None = ..., + paxcounter: meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig | None = ..., + version: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry", "version", b"version"]) -> None: ... + +global___LocalModuleConfig = LocalModuleConfig diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py new file mode 100644 index 0000000..684b513 --- /dev/null +++ b/meshtastic/protobuf/mesh_pb2.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/mesh.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 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 module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 +from meshtastic.protobuf import portnums_pb2 as meshtastic_dot_protobuf_dot_portnums__pb2 +from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__pb2 +from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xeb\x08\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"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.mesh_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _USER.fields_by_name['macaddr']._options = None + _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' + _MESHPACKET.fields_by_name['delayed']._options = None + _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' + _globals['_HARDWAREMODEL']._serialized_start=5442 + _globals['_HARDWAREMODEL']._serialized_end=6573 + _globals['_CONSTANTS']._serialized_start=6575 + _globals['_CONSTANTS']._serialized_end=6619 + _globals['_CRITICALERRORCODE']._serialized_start=6622 + _globals['_CRITICALERRORCODE']._serialized_end=6860 + _globals['_POSITION']._serialized_start=273 + _globals['_POSITION']._serialized_end=1032 + _globals['_POSITION_LOCSOURCE']._serialized_start=854 + _globals['_POSITION_LOCSOURCE']._serialized_end=932 + _globals['_POSITION_ALTSOURCE']._serialized_start=934 + _globals['_POSITION_ALTSOURCE']._serialized_end=1032 + _globals['_USER']._serialized_start=1035 + _globals['_USER']._serialized_end=1249 + _globals['_ROUTEDISCOVERY']._serialized_start=1251 + _globals['_ROUTEDISCOVERY']._serialized_end=1282 + _globals['_ROUTING']._serialized_start=1285 + _globals['_ROUTING']._serialized_end=1692 + _globals['_ROUTING_ERROR']._serialized_start=1479 + _globals['_ROUTING_ERROR']._serialized_end=1681 + _globals['_DATA']._serialized_start=1695 + _globals['_DATA']._serialized_end=1871 + _globals['_WAYPOINT']._serialized_start=1874 + _globals['_WAYPOINT']._serialized_end=2021 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2023 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2131 + _globals['_MESHPACKET']._serialized_start=2134 + _globals['_MESHPACKET']._serialized_end=2694 + _globals['_MESHPACKET_PRIORITY']._serialized_start=2516 + _globals['_MESHPACKET_PRIORITY']._serialized_end=2607 + _globals['_MESHPACKET_DELAYED']._serialized_start=2609 + _globals['_MESHPACKET_DELAYED']._serialized_end=2675 + _globals['_NODEINFO']._serialized_start=2697 + _globals['_NODEINFO']._serialized_end=2978 + _globals['_MYNODEINFO']._serialized_start=2980 + _globals['_MYNODEINFO']._serialized_end=3060 + _globals['_LOGRECORD']._serialized_start=3063 + _globals['_LOGRECORD']._serialized_end=3264 + _globals['_LOGRECORD_LEVEL']._serialized_start=3176 + _globals['_LOGRECORD_LEVEL']._serialized_end=3264 + _globals['_QUEUESTATUS']._serialized_start=3266 + _globals['_QUEUESTATUS']._serialized_end=3346 + _globals['_FROMRADIO']._serialized_start=3349 + _globals['_FROMRADIO']._serialized_end=4051 + _globals['_TORADIO']._serialized_start=4054 + _globals['_TORADIO']._serialized_end=4366 + _globals['_COMPRESSED']._serialized_start=4368 + _globals['_COMPRESSED']._serialized_end=4441 + _globals['_NEIGHBORINFO']._serialized_start=4444 + _globals['_NEIGHBORINFO']._serialized_end=4588 + _globals['_NEIGHBOR']._serialized_start=4590 + _globals['_NEIGHBOR']._serialized_end=4690 + _globals['_DEVICEMETADATA']._serialized_start=4693 + _globals['_DEVICEMETADATA']._serialized_end=5012 + _globals['_HEARTBEAT']._serialized_start=5014 + _globals['_HEARTBEAT']._serialized_end=5025 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5027 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5121 + _globals['_CHUNKEDPAYLOAD']._serialized_start=5123 + _globals['_CHUNKEDPAYLOAD']._serialized_end=5224 + _globals['_RESEND_CHUNKS']._serialized_start=5226 + _globals['_RESEND_CHUNKS']._serialized_end=5257 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5260 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=5439 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi new file mode 100644 index 0000000..89b0a75 --- /dev/null +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -0,0 +1,2552 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import meshtastic.protobuf.channel_pb2 +import meshtastic.protobuf.config_pb2 +import meshtastic.protobuf.module_config_pb2 +import meshtastic.protobuf.portnums_pb2 +import meshtastic.protobuf.telemetry_pb2 +import meshtastic.protobuf.xmodem_pb2 +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 _HardwareModel: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_HardwareModel.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: _HardwareModel.ValueType # 0 + """ + TODO: REPLACE + """ + TLORA_V2: _HardwareModel.ValueType # 1 + """ + TODO: REPLACE + """ + TLORA_V1: _HardwareModel.ValueType # 2 + """ + TODO: REPLACE + """ + TLORA_V2_1_1P6: _HardwareModel.ValueType # 3 + """ + TODO: REPLACE + """ + TBEAM: _HardwareModel.ValueType # 4 + """ + TODO: REPLACE + """ + HELTEC_V2_0: _HardwareModel.ValueType # 5 + """ + The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 + (see HELTEC_V2 for the new version). + """ + TBEAM_V0P7: _HardwareModel.ValueType # 6 + """ + TODO: REPLACE + """ + T_ECHO: _HardwareModel.ValueType # 7 + """ + TODO: REPLACE + """ + TLORA_V1_1P3: _HardwareModel.ValueType # 8 + """ + TODO: REPLACE + """ + RAK4631: _HardwareModel.ValueType # 9 + """ + TODO: REPLACE + """ + HELTEC_V2_1: _HardwareModel.ValueType # 10 + """ + The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. + Sadly they did not update anything on the silkscreen to identify this board + """ + HELTEC_V1: _HardwareModel.ValueType # 11 + """ + Ancient heltec WiFi_Lora_32 board + """ + LILYGO_TBEAM_S3_CORE: _HardwareModel.ValueType # 12 + """ + New T-BEAM with ESP32-S3 CPU + """ + RAK11200: _HardwareModel.ValueType # 13 + """ + RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ + """ + NANO_G1: _HardwareModel.ValueType # 14 + """ + B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano + """ + TLORA_V2_1_1P8: _HardwareModel.ValueType # 15 + """ + TODO: REPLACE + """ + TLORA_T3_S3: _HardwareModel.ValueType # 16 + """ + TODO: REPLACE + """ + NANO_G1_EXPLORER: _HardwareModel.ValueType # 17 + """ + B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer + """ + NANO_G2_ULTRA: _HardwareModel.ValueType # 18 + """ + B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra + """ + LORA_TYPE: _HardwareModel.ValueType # 19 + """ + LoRAType device: https://loratype.org/ + """ + WIPHONE: _HardwareModel.ValueType # 20 + """ + wiphone https://www.wiphone.io/ + """ + WIO_WM1110: _HardwareModel.ValueType # 21 + """ + WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk + """ + STATION_G1: _HardwareModel.ValueType # 25 + """ + B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station + """ + RAK11310: _HardwareModel.ValueType # 26 + """ + RAK11310 (RP2040 + SX1262) + """ + SENSELORA_RP2040: _HardwareModel.ValueType # 27 + """ + Makerfabs SenseLoRA Receiver (RP2040 + RFM96) + """ + SENSELORA_S3: _HardwareModel.ValueType # 28 + """ + Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) + """ + CANARYONE: _HardwareModel.ValueType # 29 + """ + Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone + """ + RP2040_LORA: _HardwareModel.ValueType # 30 + """ + Waveshare RP2040 LoRa - https://www.waveshare.com/rp2040-lora.htm + """ + STATION_G2: _HardwareModel.ValueType # 31 + """ + B&Q Consulting Station G2: https://wiki.uniteng.com/en/meshtastic/station-g2 + """ + LORA_RELAY_V1: _HardwareModel.ValueType # 32 + """ + --------------------------------------------------------------------------- + Less common/prototype boards listed here (needs one more byte over the air) + --------------------------------------------------------------------------- + """ + NRF52840DK: _HardwareModel.ValueType # 33 + """ + TODO: REPLACE + """ + PPR: _HardwareModel.ValueType # 34 + """ + TODO: REPLACE + """ + GENIEBLOCKS: _HardwareModel.ValueType # 35 + """ + TODO: REPLACE + """ + NRF52_UNKNOWN: _HardwareModel.ValueType # 36 + """ + TODO: REPLACE + """ + PORTDUINO: _HardwareModel.ValueType # 37 + """ + TODO: REPLACE + """ + ANDROID_SIM: _HardwareModel.ValueType # 38 + """ + The simulator built into the android app + """ + DIY_V1: _HardwareModel.ValueType # 39 + """ + Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics + """ + NRF52840_PCA10059: _HardwareModel.ValueType # 40 + """ + nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ + """ + DR_DEV: _HardwareModel.ValueType # 41 + """ + Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 + """ + M5STACK: _HardwareModel.ValueType # 42 + """ + M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ + """ + HELTEC_V3: _HardwareModel.ValueType # 43 + """ + New Heltec LoRA32 with ESP32-S3 CPU + """ + HELTEC_WSL_V3: _HardwareModel.ValueType # 44 + """ + New Heltec Wireless Stick Lite with ESP32-S3 CPU + """ + BETAFPV_2400_TX: _HardwareModel.ValueType # 45 + """ + New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU + """ + BETAFPV_900_NANO_TX: _HardwareModel.ValueType # 46 + """ + BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU + """ + RPI_PICO: _HardwareModel.ValueType # 47 + """ + Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module + """ + HELTEC_WIRELESS_TRACKER: _HardwareModel.ValueType # 48 + """ + Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT + Newer V1.1, version is written on the PCB near the display. + """ + HELTEC_WIRELESS_PAPER: _HardwareModel.ValueType # 49 + """ + Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display + """ + T_DECK: _HardwareModel.ValueType # 50 + """ + LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display + """ + T_WATCH_S3: _HardwareModel.ValueType # 51 + """ + LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display + """ + PICOMPUTER_S3: _HardwareModel.ValueType # 52 + """ + Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display + """ + HELTEC_HT62: _HardwareModel.ValueType # 53 + """ + Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa + """ + EBYTE_ESP32_S3: _HardwareModel.ValueType # 54 + """ + EBYTE SPI LoRa module and ESP32-S3 + """ + ESP32_S3_PICO: _HardwareModel.ValueType # 55 + """ + Waveshare ESP32-S3-PICO with PICO LoRa HAT and 2.9inch e-Ink + """ + CHATTER_2: _HardwareModel.ValueType # 56 + """ + CircuitMess Chatter 2 LLCC68 Lora Module and ESP32 Wroom + Lora module can be swapped out for a Heltec RA-62 which is "almost" pin compatible + with one cut and one jumper Meshtastic works + """ + HELTEC_WIRELESS_PAPER_V1_0: _HardwareModel.ValueType # 57 + """ + Heltec Wireless Paper, With ESP32-S3 CPU and E-Ink display + Older "V1.0" Variant, has no "version sticker" + E-Ink model is DEPG0213BNS800 + Tab on the screen protector is RED + Flex connector marking is FPC-7528B + """ + HELTEC_WIRELESS_TRACKER_V1_0: _HardwareModel.ValueType # 58 + """ + Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT + Older "V1.0" Variant + """ + UNPHONE: _HardwareModel.ValueType # 59 + """ + unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope + """ + TD_LORAC: _HardwareModel.ValueType # 60 + """ + Teledatics TD-LORAC NRF52840 based M.2 LoRA module + Compatible with the TD-WRLS development board + """ + CDEBYTE_EORA_S3: _HardwareModel.ValueType # 61 + """ + CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 + """ + TWC_MESH_V4: _HardwareModel.ValueType # 62 + """ + TWC_MESH_V4 + Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS + """ + NRF52_PROMICRO_DIY: _HardwareModel.ValueType # 63 + """ + NRF52_PROMICRO_DIY + Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS + """ + RADIOMASTER_900_BANDIT_NANO: _HardwareModel.ValueType # 64 + """ + RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module + ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS + """ + PRIVATE_HW: _HardwareModel.ValueType # 255 + """ + ------------------------------------------------------------------------------------------------------------------------------------------ + Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. + ------------------------------------------------------------------------------------------------------------------------------------------ + """ + +class HardwareModel(_HardwareModel, metaclass=_HardwareModelEnumTypeWrapper): + """ + Note: these enum names must EXACTLY match the string used in the device + bin/build-all.sh script. + Because they will be used to find firmware filenames in the android app for OTA updates. + To match the old style filenames, _ is converted to -, p is converted to . + """ + +UNSET: HardwareModel.ValueType # 0 +""" +TODO: REPLACE +""" +TLORA_V2: HardwareModel.ValueType # 1 +""" +TODO: REPLACE +""" +TLORA_V1: HardwareModel.ValueType # 2 +""" +TODO: REPLACE +""" +TLORA_V2_1_1P6: HardwareModel.ValueType # 3 +""" +TODO: REPLACE +""" +TBEAM: HardwareModel.ValueType # 4 +""" +TODO: REPLACE +""" +HELTEC_V2_0: HardwareModel.ValueType # 5 +""" +The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 +(see HELTEC_V2 for the new version). +""" +TBEAM_V0P7: HardwareModel.ValueType # 6 +""" +TODO: REPLACE +""" +T_ECHO: HardwareModel.ValueType # 7 +""" +TODO: REPLACE +""" +TLORA_V1_1P3: HardwareModel.ValueType # 8 +""" +TODO: REPLACE +""" +RAK4631: HardwareModel.ValueType # 9 +""" +TODO: REPLACE +""" +HELTEC_V2_1: HardwareModel.ValueType # 10 +""" +The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. +Sadly they did not update anything on the silkscreen to identify this board +""" +HELTEC_V1: HardwareModel.ValueType # 11 +""" +Ancient heltec WiFi_Lora_32 board +""" +LILYGO_TBEAM_S3_CORE: HardwareModel.ValueType # 12 +""" +New T-BEAM with ESP32-S3 CPU +""" +RAK11200: HardwareModel.ValueType # 13 +""" +RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ +""" +NANO_G1: HardwareModel.ValueType # 14 +""" +B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano +""" +TLORA_V2_1_1P8: HardwareModel.ValueType # 15 +""" +TODO: REPLACE +""" +TLORA_T3_S3: HardwareModel.ValueType # 16 +""" +TODO: REPLACE +""" +NANO_G1_EXPLORER: HardwareModel.ValueType # 17 +""" +B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer +""" +NANO_G2_ULTRA: HardwareModel.ValueType # 18 +""" +B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra +""" +LORA_TYPE: HardwareModel.ValueType # 19 +""" +LoRAType device: https://loratype.org/ +""" +WIPHONE: HardwareModel.ValueType # 20 +""" +wiphone https://www.wiphone.io/ +""" +WIO_WM1110: HardwareModel.ValueType # 21 +""" +WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk +""" +STATION_G1: HardwareModel.ValueType # 25 +""" +B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station +""" +RAK11310: HardwareModel.ValueType # 26 +""" +RAK11310 (RP2040 + SX1262) +""" +SENSELORA_RP2040: HardwareModel.ValueType # 27 +""" +Makerfabs SenseLoRA Receiver (RP2040 + RFM96) +""" +SENSELORA_S3: HardwareModel.ValueType # 28 +""" +Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) +""" +CANARYONE: HardwareModel.ValueType # 29 +""" +Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone +""" +RP2040_LORA: HardwareModel.ValueType # 30 +""" +Waveshare RP2040 LoRa - https://www.waveshare.com/rp2040-lora.htm +""" +STATION_G2: HardwareModel.ValueType # 31 +""" +B&Q Consulting Station G2: https://wiki.uniteng.com/en/meshtastic/station-g2 +""" +LORA_RELAY_V1: HardwareModel.ValueType # 32 +""" +--------------------------------------------------------------------------- +Less common/prototype boards listed here (needs one more byte over the air) +--------------------------------------------------------------------------- +""" +NRF52840DK: HardwareModel.ValueType # 33 +""" +TODO: REPLACE +""" +PPR: HardwareModel.ValueType # 34 +""" +TODO: REPLACE +""" +GENIEBLOCKS: HardwareModel.ValueType # 35 +""" +TODO: REPLACE +""" +NRF52_UNKNOWN: HardwareModel.ValueType # 36 +""" +TODO: REPLACE +""" +PORTDUINO: HardwareModel.ValueType # 37 +""" +TODO: REPLACE +""" +ANDROID_SIM: HardwareModel.ValueType # 38 +""" +The simulator built into the android app +""" +DIY_V1: HardwareModel.ValueType # 39 +""" +Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics +""" +NRF52840_PCA10059: HardwareModel.ValueType # 40 +""" +nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ +""" +DR_DEV: HardwareModel.ValueType # 41 +""" +Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 +""" +M5STACK: HardwareModel.ValueType # 42 +""" +M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ +""" +HELTEC_V3: HardwareModel.ValueType # 43 +""" +New Heltec LoRA32 with ESP32-S3 CPU +""" +HELTEC_WSL_V3: HardwareModel.ValueType # 44 +""" +New Heltec Wireless Stick Lite with ESP32-S3 CPU +""" +BETAFPV_2400_TX: HardwareModel.ValueType # 45 +""" +New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU +""" +BETAFPV_900_NANO_TX: HardwareModel.ValueType # 46 +""" +BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU +""" +RPI_PICO: HardwareModel.ValueType # 47 +""" +Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module +""" +HELTEC_WIRELESS_TRACKER: HardwareModel.ValueType # 48 +""" +Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT +Newer V1.1, version is written on the PCB near the display. +""" +HELTEC_WIRELESS_PAPER: HardwareModel.ValueType # 49 +""" +Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display +""" +T_DECK: HardwareModel.ValueType # 50 +""" +LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display +""" +T_WATCH_S3: HardwareModel.ValueType # 51 +""" +LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display +""" +PICOMPUTER_S3: HardwareModel.ValueType # 52 +""" +Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display +""" +HELTEC_HT62: HardwareModel.ValueType # 53 +""" +Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa +""" +EBYTE_ESP32_S3: HardwareModel.ValueType # 54 +""" +EBYTE SPI LoRa module and ESP32-S3 +""" +ESP32_S3_PICO: HardwareModel.ValueType # 55 +""" +Waveshare ESP32-S3-PICO with PICO LoRa HAT and 2.9inch e-Ink +""" +CHATTER_2: HardwareModel.ValueType # 56 +""" +CircuitMess Chatter 2 LLCC68 Lora Module and ESP32 Wroom +Lora module can be swapped out for a Heltec RA-62 which is "almost" pin compatible +with one cut and one jumper Meshtastic works +""" +HELTEC_WIRELESS_PAPER_V1_0: HardwareModel.ValueType # 57 +""" +Heltec Wireless Paper, With ESP32-S3 CPU and E-Ink display +Older "V1.0" Variant, has no "version sticker" +E-Ink model is DEPG0213BNS800 +Tab on the screen protector is RED +Flex connector marking is FPC-7528B +""" +HELTEC_WIRELESS_TRACKER_V1_0: HardwareModel.ValueType # 58 +""" +Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT +Older "V1.0" Variant +""" +UNPHONE: HardwareModel.ValueType # 59 +""" +unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope +""" +TD_LORAC: HardwareModel.ValueType # 60 +""" +Teledatics TD-LORAC NRF52840 based M.2 LoRA module +Compatible with the TD-WRLS development board +""" +CDEBYTE_EORA_S3: HardwareModel.ValueType # 61 +""" +CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 +""" +TWC_MESH_V4: HardwareModel.ValueType # 62 +""" +TWC_MESH_V4 +Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS +""" +NRF52_PROMICRO_DIY: HardwareModel.ValueType # 63 +""" +NRF52_PROMICRO_DIY +Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS +""" +RADIOMASTER_900_BANDIT_NANO: HardwareModel.ValueType # 64 +""" +RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module +ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS +""" +PRIVATE_HW: HardwareModel.ValueType # 255 +""" +------------------------------------------------------------------------------------------------------------------------------------------ +Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. +------------------------------------------------------------------------------------------------------------------------------------------ +""" +global___HardwareModel = HardwareModel + +class _Constants: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ConstantsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Constants.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ZERO: _Constants.ValueType # 0 + """ + First enum must be zero, and we are just using this enum to + pass int constants between two very different environments + """ + DATA_PAYLOAD_LEN: _Constants.ValueType # 237 + """ + From mesh.options + note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is + outside of this envelope + """ + +class Constants(_Constants, metaclass=_ConstantsEnumTypeWrapper): + """ + Shared constants between device and phone + """ + +ZERO: Constants.ValueType # 0 +""" +First enum must be zero, and we are just using this enum to +pass int constants between two very different environments +""" +DATA_PAYLOAD_LEN: Constants.ValueType # 237 +""" +From mesh.options +note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is +outside of this envelope +""" +global___Constants = Constants + +class _CriticalErrorCode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CriticalErrorCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CriticalErrorCode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NONE: _CriticalErrorCode.ValueType # 0 + """ + TODO: REPLACE + """ + TX_WATCHDOG: _CriticalErrorCode.ValueType # 1 + """ + A software bug was detected while trying to send lora + """ + SLEEP_ENTER_WAIT: _CriticalErrorCode.ValueType # 2 + """ + A software bug was detected on entry to sleep + """ + NO_RADIO: _CriticalErrorCode.ValueType # 3 + """ + No Lora radio hardware could be found + """ + UNSPECIFIED: _CriticalErrorCode.ValueType # 4 + """ + Not normally used + """ + UBLOX_UNIT_FAILED: _CriticalErrorCode.ValueType # 5 + """ + We failed while configuring a UBlox GPS + """ + NO_AXP192: _CriticalErrorCode.ValueType # 6 + """ + This board was expected to have a power management chip and it is missing or broken + """ + INVALID_RADIO_SETTING: _CriticalErrorCode.ValueType # 7 + """ + The channel tried to set a radio setting which is not supported by this chipset, + radio comms settings are now undefined. + """ + TRANSMIT_FAILED: _CriticalErrorCode.ValueType # 8 + """ + Radio transmit hardware failure. We sent data to the radio chip, but it didn't + reply with an interrupt. + """ + BROWNOUT: _CriticalErrorCode.ValueType # 9 + """ + We detected that the main CPU voltage dropped below the minimum acceptable value + """ + SX1262_FAILURE: _CriticalErrorCode.ValueType # 10 + """Selftest of SX1262 radio chip failed""" + RADIO_SPI_BUG: _CriticalErrorCode.ValueType # 11 + """ + A (likely software but possibly hardware) failure was detected while trying to send packets. + If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug + """ + +class CriticalErrorCode(_CriticalErrorCode, metaclass=_CriticalErrorCodeEnumTypeWrapper): + """ + Error codes for critical errors + The device might report these fault codes on the screen. + If you encounter a fault code, please post on the meshtastic.discourse.group + and we'll try to help. + """ + +NONE: CriticalErrorCode.ValueType # 0 +""" +TODO: REPLACE +""" +TX_WATCHDOG: CriticalErrorCode.ValueType # 1 +""" +A software bug was detected while trying to send lora +""" +SLEEP_ENTER_WAIT: CriticalErrorCode.ValueType # 2 +""" +A software bug was detected on entry to sleep +""" +NO_RADIO: CriticalErrorCode.ValueType # 3 +""" +No Lora radio hardware could be found +""" +UNSPECIFIED: CriticalErrorCode.ValueType # 4 +""" +Not normally used +""" +UBLOX_UNIT_FAILED: CriticalErrorCode.ValueType # 5 +""" +We failed while configuring a UBlox GPS +""" +NO_AXP192: CriticalErrorCode.ValueType # 6 +""" +This board was expected to have a power management chip and it is missing or broken +""" +INVALID_RADIO_SETTING: CriticalErrorCode.ValueType # 7 +""" +The channel tried to set a radio setting which is not supported by this chipset, +radio comms settings are now undefined. +""" +TRANSMIT_FAILED: CriticalErrorCode.ValueType # 8 +""" +Radio transmit hardware failure. We sent data to the radio chip, but it didn't +reply with an interrupt. +""" +BROWNOUT: CriticalErrorCode.ValueType # 9 +""" +We detected that the main CPU voltage dropped below the minimum acceptable value +""" +SX1262_FAILURE: CriticalErrorCode.ValueType # 10 +"""Selftest of SX1262 radio chip failed""" +RADIO_SPI_BUG: CriticalErrorCode.ValueType # 11 +""" +A (likely software but possibly hardware) failure was detected while trying to send packets. +If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug +""" +global___CriticalErrorCode = CriticalErrorCode + +@typing.final +class Position(google.protobuf.message.Message): + """ + a gps position + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _LocSource: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _LocSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Position._LocSource.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LOC_UNSET: Position._LocSource.ValueType # 0 + """ + TODO: REPLACE + """ + LOC_MANUAL: Position._LocSource.ValueType # 1 + """ + TODO: REPLACE + """ + LOC_INTERNAL: Position._LocSource.ValueType # 2 + """ + TODO: REPLACE + """ + LOC_EXTERNAL: Position._LocSource.ValueType # 3 + """ + TODO: REPLACE + """ + + class LocSource(_LocSource, metaclass=_LocSourceEnumTypeWrapper): + """ + How the location was acquired: manual, onboard GPS, external (EUD) GPS + """ + + LOC_UNSET: Position.LocSource.ValueType # 0 + """ + TODO: REPLACE + """ + LOC_MANUAL: Position.LocSource.ValueType # 1 + """ + TODO: REPLACE + """ + LOC_INTERNAL: Position.LocSource.ValueType # 2 + """ + TODO: REPLACE + """ + LOC_EXTERNAL: Position.LocSource.ValueType # 3 + """ + TODO: REPLACE + """ + + class _AltSource: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _AltSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Position._AltSource.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ALT_UNSET: Position._AltSource.ValueType # 0 + """ + TODO: REPLACE + """ + ALT_MANUAL: Position._AltSource.ValueType # 1 + """ + TODO: REPLACE + """ + ALT_INTERNAL: Position._AltSource.ValueType # 2 + """ + TODO: REPLACE + """ + ALT_EXTERNAL: Position._AltSource.ValueType # 3 + """ + TODO: REPLACE + """ + ALT_BAROMETRIC: Position._AltSource.ValueType # 4 + """ + TODO: REPLACE + """ + + class AltSource(_AltSource, metaclass=_AltSourceEnumTypeWrapper): + """ + How the altitude was acquired: manual, GPS int/ext, etc + Default: same as location_source if present + """ + + ALT_UNSET: Position.AltSource.ValueType # 0 + """ + TODO: REPLACE + """ + ALT_MANUAL: Position.AltSource.ValueType # 1 + """ + TODO: REPLACE + """ + ALT_INTERNAL: Position.AltSource.ValueType # 2 + """ + TODO: REPLACE + """ + ALT_EXTERNAL: Position.AltSource.ValueType # 3 + """ + TODO: REPLACE + """ + ALT_BAROMETRIC: Position.AltSource.ValueType # 4 + """ + TODO: REPLACE + """ + + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + ALTITUDE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LOCATION_SOURCE_FIELD_NUMBER: builtins.int + ALTITUDE_SOURCE_FIELD_NUMBER: builtins.int + TIMESTAMP_FIELD_NUMBER: builtins.int + TIMESTAMP_MILLIS_ADJUST_FIELD_NUMBER: builtins.int + ALTITUDE_HAE_FIELD_NUMBER: builtins.int + ALTITUDE_GEOIDAL_SEPARATION_FIELD_NUMBER: builtins.int + PDOP_FIELD_NUMBER: builtins.int + HDOP_FIELD_NUMBER: builtins.int + VDOP_FIELD_NUMBER: builtins.int + GPS_ACCURACY_FIELD_NUMBER: builtins.int + GROUND_SPEED_FIELD_NUMBER: builtins.int + GROUND_TRACK_FIELD_NUMBER: builtins.int + FIX_QUALITY_FIELD_NUMBER: builtins.int + FIX_TYPE_FIELD_NUMBER: builtins.int + SATS_IN_VIEW_FIELD_NUMBER: builtins.int + SENSOR_ID_FIELD_NUMBER: builtins.int + NEXT_UPDATE_FIELD_NUMBER: builtins.int + SEQ_NUMBER_FIELD_NUMBER: builtins.int + PRECISION_BITS_FIELD_NUMBER: builtins.int + latitude_i: builtins.int + """ + The new preferred location encoding, multiply by 1e-7 to get degrees + in floating point + """ + longitude_i: builtins.int + """ + TODO: REPLACE + """ + altitude: builtins.int + """ + In meters above MSL (but see issue #359) + """ + time: builtins.int + """ + This is usually not sent over the mesh (to save space), but it is sent + from the phone so that the local device can set its time if it is sent over + the mesh (because there are devices on the mesh without GPS or RTC). + seconds since 1970 + """ + location_source: global___Position.LocSource.ValueType + """ + TODO: REPLACE + """ + altitude_source: global___Position.AltSource.ValueType + """ + TODO: REPLACE + """ + timestamp: builtins.int + """ + Positional timestamp (actual timestamp of GPS solution) in integer epoch seconds + """ + timestamp_millis_adjust: builtins.int + """ + Pos. timestamp milliseconds adjustment (rarely available or required) + """ + altitude_hae: builtins.int + """ + HAE altitude in meters - can be used instead of MSL altitude + """ + altitude_geoidal_separation: builtins.int + """ + Geoidal separation in meters + """ + PDOP: builtins.int + """ + Horizontal, Vertical and Position Dilution of Precision, in 1/100 units + - PDOP is sufficient for most cases + - for higher precision scenarios, HDOP and VDOP can be used instead, + in which case PDOP becomes redundant (PDOP=sqrt(HDOP^2 + VDOP^2)) + TODO: REMOVE/INTEGRATE + """ + HDOP: builtins.int + """ + TODO: REPLACE + """ + VDOP: builtins.int + """ + TODO: REPLACE + """ + gps_accuracy: builtins.int + """ + GPS accuracy (a hardware specific constant) in mm + multiplied with DOP to calculate positional accuracy + Default: "'bout three meters-ish" :) + """ + ground_speed: builtins.int + """ + Ground speed in m/s and True North TRACK in 1/100 degrees + Clarification of terms: + - "track" is the direction of motion (measured in horizontal plane) + - "heading" is where the fuselage points (measured in horizontal plane) + - "yaw" indicates a relative rotation about the vertical axis + TODO: REMOVE/INTEGRATE + """ + ground_track: builtins.int + """ + TODO: REPLACE + """ + fix_quality: builtins.int + """ + GPS fix quality (from NMEA GxGGA statement or similar) + """ + fix_type: builtins.int + """ + GPS fix type 2D/3D (from NMEA GxGSA statement) + """ + sats_in_view: builtins.int + """ + GPS "Satellites in View" number + """ + sensor_id: builtins.int + """ + Sensor ID - in case multiple positioning sensors are being used + """ + next_update: builtins.int + """ + Estimated/expected time (in seconds) until next update: + - if we update at fixed intervals of X seconds, use X + - if we update at dynamic intervals (based on relative movement etc), + but "AT LEAST every Y seconds", use Y + """ + seq_number: builtins.int + """ + A sequence number, incremented with each Position message to help + detect lost updates if needed + """ + precision_bits: builtins.int + """ + Indicates the bits of precision set by the sending node + """ + def __init__( + self, + *, + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + altitude: builtins.int = ..., + time: builtins.int = ..., + location_source: global___Position.LocSource.ValueType = ..., + altitude_source: global___Position.AltSource.ValueType = ..., + timestamp: builtins.int = ..., + timestamp_millis_adjust: builtins.int = ..., + altitude_hae: builtins.int = ..., + altitude_geoidal_separation: builtins.int = ..., + PDOP: builtins.int = ..., + HDOP: builtins.int = ..., + VDOP: builtins.int = ..., + gps_accuracy: builtins.int = ..., + ground_speed: builtins.int = ..., + ground_track: builtins.int = ..., + fix_quality: builtins.int = ..., + fix_type: builtins.int = ..., + sats_in_view: builtins.int = ..., + sensor_id: builtins.int = ..., + next_update: builtins.int = ..., + seq_number: builtins.int = ..., + precision_bits: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["HDOP", b"HDOP", "PDOP", b"PDOP", "VDOP", b"VDOP", "altitude", b"altitude", "altitude_geoidal_separation", b"altitude_geoidal_separation", "altitude_hae", b"altitude_hae", "altitude_source", b"altitude_source", "fix_quality", b"fix_quality", "fix_type", b"fix_type", "gps_accuracy", b"gps_accuracy", "ground_speed", b"ground_speed", "ground_track", b"ground_track", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "next_update", b"next_update", "precision_bits", b"precision_bits", "sats_in_view", b"sats_in_view", "sensor_id", b"sensor_id", "seq_number", b"seq_number", "time", b"time", "timestamp", b"timestamp", "timestamp_millis_adjust", b"timestamp_millis_adjust"]) -> None: ... + +global___Position = Position + +@typing.final +class User(google.protobuf.message.Message): + """ + Broadcast when a newly powered mesh node wants to find a node num it can use + Sent from the phone over bluetooth to set the user id for the owner of this node. + Also sent from nodes to each other when a new node signs on (so all clients can have this info) + The algorithm is as follows: + when a node starts up, it broadcasts their user and the normal flow is for all + other nodes to reply with their User as well (so the new node can build its nodedb) + If a node ever receives a User (not just the first broadcast) message where + the sender node number equals our node number, that indicates a collision has + occurred and the following steps should happen: + If the receiving node (that was already in the mesh)'s macaddr is LOWER than the + new User who just tried to sign in: it gets to keep its nodenum. + We send a broadcast message of OUR User (we use a broadcast so that the other node can + receive our message, considering we have the same id - it also serves to let + observers correct their nodedb) - this case is rare so it should be okay. + If any node receives a User where the macaddr is GTE than their local macaddr, + they have been vetoed and should pick a new random nodenum (filtering against + whatever it knows about the nodedb) and rebroadcast their User. + A few nodenums are reserved and will never be requested: + 0xff - broadcast + 0 through 3 - for future use + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + LONG_NAME_FIELD_NUMBER: builtins.int + SHORT_NAME_FIELD_NUMBER: builtins.int + MACADDR_FIELD_NUMBER: builtins.int + HW_MODEL_FIELD_NUMBER: builtins.int + IS_LICENSED_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + id: builtins.str + """ + A globally unique ID string for this user. + In the case of Signal that would mean +16504442323, for the default macaddr derived id it would be !<8 hexidecimal bytes>. + Note: app developers are encouraged to also use the following standard + node IDs "^all" (for broadcast), "^local" (for the locally connected node) + """ + long_name: builtins.str + """ + A full name for this user, i.e. "Kevin Hester" + """ + short_name: builtins.str + """ + A VERY short name, ideally two characters. + Suitable for a tiny OLED screen + """ + macaddr: builtins.bytes + """ + Deprecated in Meshtastic 2.1.x + This is the addr of the radio. + Not populated by the phone, but added by the esp32 when broadcasting + """ + hw_model: global___HardwareModel.ValueType + """ + TBEAM, HELTEC, etc... + Starting in 1.2.11 moved to hw_model enum in the NodeInfo object. + Apps will still need the string here for older builds + (so OTA update can find the right image), but if the enum is available it will be used instead. + """ + is_licensed: builtins.bool + """ + In some regions Ham radio operators have different bandwidth limitations than others. + If this user is a licensed operator, set this flag. + Also, "long_name" should be their licence number. + """ + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType + """ + Indicates that the user's role in the mesh + """ + def __init__( + self, + *, + id: builtins.str = ..., + long_name: builtins.str = ..., + short_name: builtins.str = ..., + macaddr: builtins.bytes = ..., + hw_model: global___HardwareModel.ValueType = ..., + is_licensed: builtins.bool = ..., + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ..., + ) -> 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", "role", b"role", "short_name", b"short_name"]) -> None: ... + +global___User = User + +@typing.final +class RouteDiscovery(google.protobuf.message.Message): + """ + A message used in our Dynamic Source Routing protocol (RFC 4728 based) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROUTE_FIELD_NUMBER: builtins.int + @property + def route(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """ + The list of nodenums this packet has visited so far + """ + + def __init__( + self, + *, + route: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["route", b"route"]) -> None: ... + +global___RouteDiscovery = RouteDiscovery + +@typing.final +class Routing(google.protobuf.message.Message): + """ + A Routing control Data packet handled by the routing module + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Error: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Routing._Error.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NONE: Routing._Error.ValueType # 0 + """ + This message is not a failure + """ + NO_ROUTE: Routing._Error.ValueType # 1 + """ + Our node doesn't have a route to the requested destination anymore. + """ + GOT_NAK: Routing._Error.ValueType # 2 + """ + We received a nak while trying to forward on your behalf + """ + TIMEOUT: Routing._Error.ValueType # 3 + """ + TODO: REPLACE + """ + NO_INTERFACE: Routing._Error.ValueType # 4 + """ + No suitable interface could be found for delivering this packet + """ + MAX_RETRANSMIT: Routing._Error.ValueType # 5 + """ + We reached the max retransmission count (typically for naive flood routing) + """ + NO_CHANNEL: Routing._Error.ValueType # 6 + """ + No suitable channel was found for sending this packet (i.e. was requested channel index disabled?) + """ + TOO_LARGE: Routing._Error.ValueType # 7 + """ + The packet was too big for sending (exceeds interface MTU after encoding) + """ + NO_RESPONSE: Routing._Error.ValueType # 8 + """ + The request had want_response set, the request reached the destination node, but no service on that node wants to send a response + (possibly due to bad channel permissions) + """ + DUTY_CYCLE_LIMIT: Routing._Error.ValueType # 9 + """ + Cannot send currently because duty cycle regulations will be violated. + """ + BAD_REQUEST: Routing._Error.ValueType # 32 + """ + The application layer service on the remote node received your request, but considered your request somehow invalid + """ + NOT_AUTHORIZED: Routing._Error.ValueType # 33 + """ + The application layer service on the remote node received your request, but considered your request not authorized + (i.e you did not send the request on the required bound channel) + """ + + class Error(_Error, metaclass=_ErrorEnumTypeWrapper): + """ + A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide + details on the type of failure). + """ + + NONE: Routing.Error.ValueType # 0 + """ + This message is not a failure + """ + NO_ROUTE: Routing.Error.ValueType # 1 + """ + Our node doesn't have a route to the requested destination anymore. + """ + GOT_NAK: Routing.Error.ValueType # 2 + """ + We received a nak while trying to forward on your behalf + """ + TIMEOUT: Routing.Error.ValueType # 3 + """ + TODO: REPLACE + """ + NO_INTERFACE: Routing.Error.ValueType # 4 + """ + No suitable interface could be found for delivering this packet + """ + MAX_RETRANSMIT: Routing.Error.ValueType # 5 + """ + We reached the max retransmission count (typically for naive flood routing) + """ + NO_CHANNEL: Routing.Error.ValueType # 6 + """ + No suitable channel was found for sending this packet (i.e. was requested channel index disabled?) + """ + TOO_LARGE: Routing.Error.ValueType # 7 + """ + The packet was too big for sending (exceeds interface MTU after encoding) + """ + NO_RESPONSE: Routing.Error.ValueType # 8 + """ + The request had want_response set, the request reached the destination node, but no service on that node wants to send a response + (possibly due to bad channel permissions) + """ + DUTY_CYCLE_LIMIT: Routing.Error.ValueType # 9 + """ + Cannot send currently because duty cycle regulations will be violated. + """ + BAD_REQUEST: Routing.Error.ValueType # 32 + """ + The application layer service on the remote node received your request, but considered your request somehow invalid + """ + NOT_AUTHORIZED: Routing.Error.ValueType # 33 + """ + The application layer service on the remote node received your request, but considered your request not authorized + (i.e you did not send the request on the required bound channel) + """ + + ROUTE_REQUEST_FIELD_NUMBER: builtins.int + ROUTE_REPLY_FIELD_NUMBER: builtins.int + ERROR_REASON_FIELD_NUMBER: builtins.int + error_reason: global___Routing.Error.ValueType + """ + A failure in delivering a message (usually used for routing control messages, but might be provided + in addition to ack.fail_id to provide details on the type of failure). + """ + @property + def route_request(self) -> global___RouteDiscovery: + """ + A route request going from the requester + """ + + @property + def route_reply(self) -> global___RouteDiscovery: + """ + A route reply + """ + + def __init__( + self, + *, + route_request: global___RouteDiscovery | None = ..., + route_reply: global___RouteDiscovery | None = ..., + error_reason: global___Routing.Error.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["error_reason", b"error_reason", "route_reply", b"route_reply", "route_request", b"route_request", "variant", b"variant"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["error_reason", b"error_reason", "route_reply", b"route_reply", "route_request", b"route_request", "variant", b"variant"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["route_request", "route_reply", "error_reason"] | None: ... + +global___Routing = Routing + +@typing.final +class Data(google.protobuf.message.Message): + """ + (Formerly called SubPacket) + The payload portion fo a packet, this is the actual bytes that are sent + inside a radio packet (because from/to are broken out by the comms library) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PORTNUM_FIELD_NUMBER: builtins.int + PAYLOAD_FIELD_NUMBER: builtins.int + WANT_RESPONSE_FIELD_NUMBER: builtins.int + DEST_FIELD_NUMBER: builtins.int + SOURCE_FIELD_NUMBER: builtins.int + REQUEST_ID_FIELD_NUMBER: builtins.int + REPLY_ID_FIELD_NUMBER: builtins.int + EMOJI_FIELD_NUMBER: builtins.int + portnum: meshtastic.protobuf.portnums_pb2.PortNum.ValueType + """ + Formerly named typ and of type Type + """ + payload: builtins.bytes + """ + TODO: REPLACE + """ + want_response: builtins.bool + """ + Not normally used, but for testing a sender can request that recipient + responds in kind (i.e. if it received a position, it should unicast back it's position). + Note: that if you set this on a broadcast you will receive many replies. + """ + dest: builtins.int + """ + The address of the destination node. + This field is is filled in by the mesh radio device software, application + layer software should never need it. + RouteDiscovery messages _must_ populate this. + Other message types might need to if they are doing multihop routing. + """ + source: builtins.int + """ + The address of the original sender for this message. + This field should _only_ be populated for reliable multihop packets (to keep + packets small). + """ + request_id: builtins.int + """ + Only used in routing or response messages. + Indicates the original message ID that this message is reporting failure on. (formerly called original_id) + """ + reply_id: builtins.int + """ + If set, this message is intened to be a reply to a previously sent message with the defined id. + """ + emoji: builtins.int + """ + Defaults to false. If true, then what is in the payload should be treated as an emoji like giving + a message a heart or poop emoji. + """ + def __init__( + self, + *, + portnum: meshtastic.protobuf.portnums_pb2.PortNum.ValueType = ..., + payload: builtins.bytes = ..., + want_response: builtins.bool = ..., + dest: builtins.int = ..., + source: builtins.int = ..., + request_id: builtins.int = ..., + reply_id: builtins.int = ..., + emoji: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dest", b"dest", "emoji", b"emoji", "payload", b"payload", "portnum", b"portnum", "reply_id", b"reply_id", "request_id", b"request_id", "source", b"source", "want_response", b"want_response"]) -> None: ... + +global___Data = Data + +@typing.final +class Waypoint(google.protobuf.message.Message): + """ + Waypoint message, used to share arbitrary locations across the mesh + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + EXPIRE_FIELD_NUMBER: builtins.int + LOCKED_TO_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + ICON_FIELD_NUMBER: builtins.int + id: builtins.int + """ + Id of the waypoint + """ + latitude_i: builtins.int + """ + latitude_i + """ + longitude_i: builtins.int + """ + longitude_i + """ + expire: builtins.int + """ + Time the waypoint is to expire (epoch) + """ + locked_to: builtins.int + """ + If greater than zero, treat the value as a nodenum only allowing them to update the waypoint. + If zero, the waypoint is open to be edited by any member of the mesh. + """ + name: builtins.str + """ + Name of the waypoint - max 30 chars + """ + description: builtins.str + """ + Description of the waypoint - max 100 chars + """ + icon: builtins.int + """ + Designator icon for the waypoint in the form of a unicode emoji + """ + def __init__( + self, + *, + id: builtins.int = ..., + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + expire: builtins.int = ..., + locked_to: builtins.int = ..., + name: builtins.str = ..., + description: builtins.str = ..., + icon: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["description", b"description", "expire", b"expire", "icon", b"icon", "id", b"id", "latitude_i", b"latitude_i", "locked_to", b"locked_to", "longitude_i", b"longitude_i", "name", b"name"]) -> None: ... + +global___Waypoint = Waypoint + +@typing.final +class MqttClientProxyMessage(google.protobuf.message.Message): + """ + This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOPIC_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + TEXT_FIELD_NUMBER: builtins.int + RETAINED_FIELD_NUMBER: builtins.int + topic: builtins.str + """ + The MQTT topic this message will be sent /received on + """ + data: builtins.bytes + """ + Bytes + """ + text: builtins.str + """ + Text + """ + retained: builtins.bool + """ + Whether the message should be retained (or not) + """ + def __init__( + self, + *, + topic: builtins.str = ..., + data: builtins.bytes = ..., + text: builtins.str = ..., + retained: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["data", b"data", "payload_variant", b"payload_variant", "text", b"text"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["data", b"data", "payload_variant", b"payload_variant", "retained", b"retained", "text", b"text", "topic", b"topic"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["data", "text"] | None: ... + +global___MqttClientProxyMessage = MqttClientProxyMessage + +@typing.final +class MeshPacket(google.protobuf.message.Message): + """ + A packet envelope sent/received over the mesh + only payload_variant is sent in the payload portion of the LORA packet. + The other fields are either not sent at all, or sent in the special 16 byte LORA header. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Priority: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _PriorityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MeshPacket._Priority.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: MeshPacket._Priority.ValueType # 0 + """ + Treated as Priority.DEFAULT + """ + MIN: MeshPacket._Priority.ValueType # 1 + """ + TODO: REPLACE + """ + BACKGROUND: MeshPacket._Priority.ValueType # 10 + """ + Background position updates are sent with very low priority - + if the link is super congested they might not go out at all + """ + DEFAULT: MeshPacket._Priority.ValueType # 64 + """ + This priority is used for most messages that don't have a priority set + """ + RELIABLE: MeshPacket._Priority.ValueType # 70 + """ + If priority is unset but the message is marked as want_ack, + assume it is important and use a slightly higher priority + """ + ACK: MeshPacket._Priority.ValueType # 120 + """ + Ack/naks are sent with very high priority to ensure that retransmission + stops as soon as possible + """ + MAX: MeshPacket._Priority.ValueType # 127 + """ + TODO: REPLACE + """ + + class Priority(_Priority, metaclass=_PriorityEnumTypeWrapper): + """ + The priority of this message for sending. + Higher priorities are sent first (when managing the transmit queue). + This field is never sent over the air, it is only used internally inside of a local device node. + API clients (either on the local node or connected directly to the node) + can set this parameter if necessary. + (values must be <= 127 to keep protobuf field to one byte in size. + Detailed background on this field: + I noticed a funny side effect of lora being so slow: Usually when making + a protocol there isn’t much need to use message priority to change the order + of transmission (because interfaces are fairly fast). + But for lora where packets can take a few seconds each, it is very important + to make sure that critical packets are sent ASAP. + In the case of meshtastic that means we want to send protocol acks as soon as possible + (to prevent unneeded retransmissions), we want routing messages to be sent next, + then messages marked as reliable and finally 'background' packets like periodic position updates. + So I bit the bullet and implemented a new (internal - not sent over the air) + field in MeshPacket called 'priority'. + And the transmission queue in the router object is now a priority queue. + """ + + UNSET: MeshPacket.Priority.ValueType # 0 + """ + Treated as Priority.DEFAULT + """ + MIN: MeshPacket.Priority.ValueType # 1 + """ + TODO: REPLACE + """ + BACKGROUND: MeshPacket.Priority.ValueType # 10 + """ + Background position updates are sent with very low priority - + if the link is super congested they might not go out at all + """ + DEFAULT: MeshPacket.Priority.ValueType # 64 + """ + This priority is used for most messages that don't have a priority set + """ + RELIABLE: MeshPacket.Priority.ValueType # 70 + """ + If priority is unset but the message is marked as want_ack, + assume it is important and use a slightly higher priority + """ + ACK: MeshPacket.Priority.ValueType # 120 + """ + Ack/naks are sent with very high priority to ensure that retransmission + stops as soon as possible + """ + MAX: MeshPacket.Priority.ValueType # 127 + """ + TODO: REPLACE + """ + + class _Delayed: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _DelayedEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MeshPacket._Delayed.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NO_DELAY: MeshPacket._Delayed.ValueType # 0 + """ + If unset, the message is being sent in real time. + """ + DELAYED_BROADCAST: MeshPacket._Delayed.ValueType # 1 + """ + The message is delayed and was originally a broadcast + """ + DELAYED_DIRECT: MeshPacket._Delayed.ValueType # 2 + """ + The message is delayed and was originally a direct message + """ + + class Delayed(_Delayed, metaclass=_DelayedEnumTypeWrapper): + """ + Identify if this is a delayed packet + """ + + NO_DELAY: MeshPacket.Delayed.ValueType # 0 + """ + If unset, the message is being sent in real time. + """ + DELAYED_BROADCAST: MeshPacket.Delayed.ValueType # 1 + """ + The message is delayed and was originally a broadcast + """ + DELAYED_DIRECT: MeshPacket.Delayed.ValueType # 2 + """ + The message is delayed and was originally a direct message + """ + + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + CHANNEL_FIELD_NUMBER: builtins.int + DECODED_FIELD_NUMBER: builtins.int + ENCRYPTED_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + RX_TIME_FIELD_NUMBER: builtins.int + RX_SNR_FIELD_NUMBER: builtins.int + HOP_LIMIT_FIELD_NUMBER: builtins.int + WANT_ACK_FIELD_NUMBER: builtins.int + PRIORITY_FIELD_NUMBER: builtins.int + RX_RSSI_FIELD_NUMBER: builtins.int + DELAYED_FIELD_NUMBER: builtins.int + VIA_MQTT_FIELD_NUMBER: builtins.int + HOP_START_FIELD_NUMBER: builtins.int + to: builtins.int + """ + The (immediate) destination for this packet + """ + channel: builtins.int + """ + (Usually) If set, this indicates the index in the secondary_channels table that this packet was sent/received on. + If unset, packet was on the primary channel. + A particular node might know only a subset of channels in use on the mesh. + Therefore channel_index is inherently a local concept and meaningless to send between nodes. + Very briefly, while sending and receiving deep inside the device Router code, this field instead + contains the 'channel hash' instead of the index. + This 'trick' is only used while the payload_variant is an 'encrypted'. + """ + encrypted: builtins.bytes + """ + TODO: REPLACE + """ + id: builtins.int + """ + A unique ID for this packet. + Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space). + Otherwise a unique ID for this packet, useful for flooding algorithms. + ID only needs to be unique on a _per sender_ basis, and it only + needs to be unique for a few minutes (long enough to last for the length of + any ACK or the completion of a mesh broadcast flood). + Note: Our crypto implementation uses this id as well. + See [crypto](/docs/overview/encryption) for details. + """ + rx_time: builtins.int + """ + The time this message was received by the esp32 (secs since 1970). + Note: this field is _never_ sent on the radio link itself (to save space) Times + are typically not sent over the mesh, but they will be added to any Packet + (chain of SubPacket) sent to the phone (so the phone can know exact time of reception) + """ + rx_snr: builtins.float + """ + *Never* sent over the radio links. + Set during reception to indicate the SNR of this packet. + Used to collect statistics on current link quality. + """ + hop_limit: builtins.int + """ + If unset treated as zero (no forwarding, send to adjacent nodes only) + if 1, allow hopping through one node, etc... + For our usecase real world topologies probably have a max of about 3. + This field is normally placed into a few of bits in the header. + """ + want_ack: builtins.bool + """ + This packet is being sent as a reliable message, we would prefer it to arrive at the destination. + We would like to receive a ack packet in response. + Broadcasts messages treat this flag specially: Since acks for broadcasts would + rapidly flood the channel, the normal ack behavior is suppressed. + Instead, the original sender listens to see if at least one node is rebroadcasting this packet (because naive flooding algorithm). + If it hears that the odds (given typical LoRa topologies) the odds are very high that every node should eventually receive the message. + So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender. + If after some time we don't hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic. + Note: This flag is normally sent in a flag bit in the header when sent over the wire + """ + priority: global___MeshPacket.Priority.ValueType + """ + The priority of this message for sending. + See MeshPacket.Priority description for more details. + """ + rx_rssi: builtins.int + """ + rssi of received packet. Only sent to phone for dispay purposes. + """ + delayed: global___MeshPacket.Delayed.ValueType + """ + Describe if this message is delayed + """ + via_mqtt: builtins.bool + """ + Describes whether this packet passed via MQTT somewhere along the path it currently took. + """ + hop_start: builtins.int + """ + Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header. + When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled. + """ + @property + def decoded(self) -> global___Data: + """ + TODO: REPLACE + """ + + def __init__( + self, + *, + to: builtins.int = ..., + channel: builtins.int = ..., + decoded: global___Data | None = ..., + encrypted: builtins.bytes = ..., + id: builtins.int = ..., + rx_time: builtins.int = ..., + rx_snr: builtins.float = ..., + hop_limit: builtins.int = ..., + want_ack: builtins.bool = ..., + priority: global___MeshPacket.Priority.ValueType = ..., + rx_rssi: builtins.int = ..., + delayed: global___MeshPacket.Delayed.ValueType = ..., + via_mqtt: builtins.bool = ..., + hop_start: builtins.int = ..., + ) -> 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", "payload_variant", b"payload_variant", "priority", b"priority", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "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 + +@typing.final +class NodeInfo(google.protobuf.message.Message): + """ + The bluetooth to device link: + Old BTLE protocol docs from TODO, merge in above and make real docs... + use protocol buffers, and NanoPB + messages from device to phone: + POSITION_UPDATE (..., time) + TEXT_RECEIVED(from, text, time) + OPAQUE_RECEIVED(from, payload, time) (for signal messages or other applications) + messages from phone to device: + SET_MYID(id, human readable long, human readable short) (send down the unique ID + string used for this node, a human readable string shown for that id, and a very + short human readable string suitable for oled screen) SEND_OPAQUE(dest, payload) + (for signal messages or other applications) SEND_TEXT(dest, text) Get all + nodes() (returns list of nodes, with full info, last time seen, loc, battery + level etc) SET_CONFIG (switches device to a new set of radio params and + preshared key, drops all existing nodes, force our node to rejoin this new group) + Full information about a node on the mesh + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NUM_FIELD_NUMBER: builtins.int + USER_FIELD_NUMBER: builtins.int + POSITION_FIELD_NUMBER: builtins.int + SNR_FIELD_NUMBER: builtins.int + LAST_HEARD_FIELD_NUMBER: builtins.int + DEVICE_METRICS_FIELD_NUMBER: builtins.int + CHANNEL_FIELD_NUMBER: builtins.int + VIA_MQTT_FIELD_NUMBER: builtins.int + HOPS_AWAY_FIELD_NUMBER: builtins.int + IS_FAVORITE_FIELD_NUMBER: builtins.int + num: builtins.int + """ + The node number + """ + snr: builtins.float + """ + Returns the Signal-to-noise ratio (SNR) of the last received message, + as measured by the receiver. Return SNR of the last received message in dB + """ + last_heard: builtins.int + """ + TODO: REMOVE/INTEGRATE + Not currently used (till full DSR deployment?) Our current preferred node node for routing - might be the same as num if + we are adjacent Or zero if we don't yet know a route to this node. + fixed32 next_hop = 5; + + + Set to indicate the last time we received a packet from this node + """ + channel: builtins.int + """ + local channel index we heard that node on. Only populated if its not the default channel. + """ + via_mqtt: builtins.bool + """ + True if we witnessed the node over MQTT instead of LoRA transport + """ + hops_away: builtins.int + """ + Number of hops away from us this node is (0 if adjacent) + """ + is_favorite: builtins.bool + """ + True if node is in our favorites list + Persists between NodeDB internal clean ups + """ + @property + def user(self) -> global___User: + """ + The user info for this node + """ + + @property + def position(self) -> global___Position: + """ + This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. + Position.time now indicates the last time we received a POSITION from that node. + """ + + @property + def device_metrics(self) -> meshtastic.protobuf.telemetry_pb2.DeviceMetrics: + """ + The latest device metrics for the node. + """ + + def __init__( + self, + *, + num: builtins.int = ..., + user: global___User | None = ..., + position: global___Position | None = ..., + snr: builtins.float = ..., + last_heard: builtins.int = ..., + device_metrics: meshtastic.protobuf.telemetry_pb2.DeviceMetrics | None = ..., + channel: builtins.int = ..., + via_mqtt: builtins.bool = ..., + hops_away: builtins.int = ..., + is_favorite: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ... + +global___NodeInfo = NodeInfo + +@typing.final +class MyNodeInfo(google.protobuf.message.Message): + """ + Unique local debugging info for this node + Note: we don't include position or the user info, because that will come in the + Sent to the phone in response to WantNodes. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MY_NODE_NUM_FIELD_NUMBER: builtins.int + REBOOT_COUNT_FIELD_NUMBER: builtins.int + MIN_APP_VERSION_FIELD_NUMBER: builtins.int + my_node_num: builtins.int + """ + Tells the phone what our node number is, default starting value is + lowbyte of macaddr, but it will be fixed if that is already in use + """ + reboot_count: builtins.int + """ + The total number of reboots this node has ever encountered + (well - since the last time we discarded preferences) + """ + min_app_version: builtins.int + """ + The minimum app version that can talk to this device. + Phone/PC apps should compare this to their build number and if too low tell the user they must update their app + """ + def __init__( + self, + *, + my_node_num: builtins.int = ..., + reboot_count: builtins.int = ..., + min_app_version: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["min_app_version", b"min_app_version", "my_node_num", b"my_node_num", "reboot_count", b"reboot_count"]) -> None: ... + +global___MyNodeInfo = MyNodeInfo + +@typing.final +class LogRecord(google.protobuf.message.Message): + """ + Debug output from the device. + To minimize the size of records inside the device code, if a time/source/level is not set + on the message it is assumed to be a continuation of the previously sent message. + This allows the device code to use fixed maxlen 64 byte strings for messages, + and then extend as needed by emitting multiple records. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Level: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _LevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[LogRecord._Level.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: LogRecord._Level.ValueType # 0 + """ + Log levels, chosen to match python logging conventions. + """ + CRITICAL: LogRecord._Level.ValueType # 50 + """ + Log levels, chosen to match python logging conventions. + """ + ERROR: LogRecord._Level.ValueType # 40 + """ + Log levels, chosen to match python logging conventions. + """ + WARNING: LogRecord._Level.ValueType # 30 + """ + Log levels, chosen to match python logging conventions. + """ + INFO: LogRecord._Level.ValueType # 20 + """ + Log levels, chosen to match python logging conventions. + """ + DEBUG: LogRecord._Level.ValueType # 10 + """ + Log levels, chosen to match python logging conventions. + """ + TRACE: LogRecord._Level.ValueType # 5 + """ + Log levels, chosen to match python logging conventions. + """ + + class Level(_Level, metaclass=_LevelEnumTypeWrapper): + """ + Log levels, chosen to match python logging conventions. + """ + + UNSET: LogRecord.Level.ValueType # 0 + """ + Log levels, chosen to match python logging conventions. + """ + CRITICAL: LogRecord.Level.ValueType # 50 + """ + Log levels, chosen to match python logging conventions. + """ + ERROR: LogRecord.Level.ValueType # 40 + """ + Log levels, chosen to match python logging conventions. + """ + WARNING: LogRecord.Level.ValueType # 30 + """ + Log levels, chosen to match python logging conventions. + """ + INFO: LogRecord.Level.ValueType # 20 + """ + Log levels, chosen to match python logging conventions. + """ + DEBUG: LogRecord.Level.ValueType # 10 + """ + Log levels, chosen to match python logging conventions. + """ + TRACE: LogRecord.Level.ValueType # 5 + """ + Log levels, chosen to match python logging conventions. + """ + + MESSAGE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + SOURCE_FIELD_NUMBER: builtins.int + LEVEL_FIELD_NUMBER: builtins.int + message: builtins.str + """ + Log levels, chosen to match python logging conventions. + """ + time: builtins.int + """ + Seconds since 1970 - or 0 for unknown/unset + """ + source: builtins.str + """ + Usually based on thread name - if known + """ + level: global___LogRecord.Level.ValueType + """ + Not yet set + """ + def __init__( + self, + *, + message: builtins.str = ..., + time: builtins.int = ..., + source: builtins.str = ..., + level: global___LogRecord.Level.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["level", b"level", "message", b"message", "source", b"source", "time", b"time"]) -> None: ... + +global___LogRecord = LogRecord + +@typing.final +class QueueStatus(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RES_FIELD_NUMBER: builtins.int + FREE_FIELD_NUMBER: builtins.int + MAXLEN_FIELD_NUMBER: builtins.int + MESH_PACKET_ID_FIELD_NUMBER: builtins.int + res: builtins.int + """Last attempt to queue status, ErrorCode""" + free: builtins.int + """Free entries in the outgoing queue""" + maxlen: builtins.int + """Maximum entries in the outgoing queue""" + mesh_packet_id: builtins.int + """What was mesh packet id that generated this response?""" + def __init__( + self, + *, + res: builtins.int = ..., + free: builtins.int = ..., + maxlen: builtins.int = ..., + mesh_packet_id: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["free", b"free", "maxlen", b"maxlen", "mesh_packet_id", b"mesh_packet_id", "res", b"res"]) -> None: ... + +global___QueueStatus = QueueStatus + +@typing.final +class FromRadio(google.protobuf.message.Message): + """ + Packets from the radio to the phone will appear on the fromRadio characteristic. + It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? + It will sit in that descriptor until consumed by the phone, + at which point the next item in the FIFO will be populated. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + PACKET_FIELD_NUMBER: builtins.int + MY_INFO_FIELD_NUMBER: builtins.int + NODE_INFO_FIELD_NUMBER: builtins.int + CONFIG_FIELD_NUMBER: builtins.int + LOG_RECORD_FIELD_NUMBER: builtins.int + CONFIG_COMPLETE_ID_FIELD_NUMBER: builtins.int + REBOOTED_FIELD_NUMBER: builtins.int + MODULECONFIG_FIELD_NUMBER: builtins.int + CHANNEL_FIELD_NUMBER: builtins.int + QUEUESTATUS_FIELD_NUMBER: builtins.int + XMODEMPACKET_FIELD_NUMBER: builtins.int + METADATA_FIELD_NUMBER: builtins.int + MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int + id: builtins.int + """ + The packet id, used to allow the phone to request missing read packets from the FIFO, + see our bluetooth docs + """ + config_complete_id: builtins.int + """ + Sent as true once the device has finished sending all of the responses to want_config + recipient should check if this ID matches our original request nonce, if + not, it means your config responses haven't started yet. + NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. + """ + rebooted: builtins.bool + """ + Sent to tell clients the radio has just rebooted. + Set to true if present. + Not used on all transports, currently just used for the serial console. + NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. + """ + @property + def packet(self) -> global___MeshPacket: + """ + Log levels, chosen to match python logging conventions. + """ + + @property + def my_info(self) -> global___MyNodeInfo: + """ + Tells the phone what our node number is, can be -1 if we've not yet joined a mesh. + NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. + """ + + @property + def node_info(self) -> global___NodeInfo: + """ + One packet is sent for each node in the on radio DB + starts over with the first node in our DB + """ + + @property + def config(self) -> meshtastic.protobuf.config_pb2.Config: + """ + Include a part of the config (was: RadioConfig radio) + """ + + @property + def log_record(self) -> global___LogRecord: + """ + Set to send debug console output over our protobuf stream + """ + + @property + def moduleConfig(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig: + """ + Include module config + """ + + @property + def channel(self) -> meshtastic.protobuf.channel_pb2.Channel: + """ + One packet is sent for each channel + """ + + @property + def queueStatus(self) -> global___QueueStatus: + """ + Queue status info + """ + + @property + def xmodemPacket(self) -> meshtastic.protobuf.xmodem_pb2.XModem: + """ + File Transfer Chunk + """ + + @property + def metadata(self) -> global___DeviceMetadata: + """ + Device metadata message + """ + + @property + def mqttClientProxyMessage(self) -> global___MqttClientProxyMessage: + """ + MQTT Client Proxy Message (device sending to client / phone for publishing to MQTT) + """ + + def __init__( + self, + *, + id: builtins.int = ..., + packet: global___MeshPacket | None = ..., + my_info: global___MyNodeInfo | None = ..., + node_info: global___NodeInfo | None = ..., + config: meshtastic.protobuf.config_pb2.Config | None = ..., + log_record: global___LogRecord | None = ..., + config_complete_id: builtins.int = ..., + rebooted: builtins.bool = ..., + moduleConfig: meshtastic.protobuf.module_config_pb2.ModuleConfig | None = ..., + channel: meshtastic.protobuf.channel_pb2.Channel | None = ..., + queueStatus: global___QueueStatus | None = ..., + xmodemPacket: meshtastic.protobuf.xmodem_pb2.XModem | None = ..., + metadata: global___DeviceMetadata | None = ..., + mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage"] | None: ... + +global___FromRadio = FromRadio + +@typing.final +class ToRadio(google.protobuf.message.Message): + """ + Packets/commands to the radio will be written (reliably) to the toRadio characteristic. + Once the write completes the phone can assume it is handled. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PACKET_FIELD_NUMBER: builtins.int + WANT_CONFIG_ID_FIELD_NUMBER: builtins.int + DISCONNECT_FIELD_NUMBER: builtins.int + XMODEMPACKET_FIELD_NUMBER: builtins.int + MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int + HEARTBEAT_FIELD_NUMBER: builtins.int + want_config_id: builtins.int + """ + Phone wants radio to send full node db to the phone, This is + typically the first packet sent to the radio when the phone gets a + bluetooth connection. The radio will respond by sending back a + MyNodeInfo, a owner, a radio config and a series of + FromRadio.node_infos, and config_complete + the integer you write into this field will be reported back in the + config_complete_id response this allows clients to never be confused by + a stale old partially sent config. + """ + disconnect: builtins.bool + """ + Tell API server we are disconnecting now. + This is useful for serial links where there is no hardware/protocol based notification that the client has dropped the link. + (Sending this message is optional for clients) + """ + @property + def packet(self) -> global___MeshPacket: + """ + Send this packet on the mesh + """ + + @property + def xmodemPacket(self) -> meshtastic.protobuf.xmodem_pb2.XModem: + """ + File Transfer Chunk + """ + + @property + def mqttClientProxyMessage(self) -> global___MqttClientProxyMessage: + """ + MQTT Client Proxy Message (for client / phone subscribed to MQTT sending to device) + """ + + @property + def heartbeat(self) -> global___Heartbeat: + """ + Heartbeat message (used to keep the device connection awake on serial) + """ + + def __init__( + self, + *, + packet: global___MeshPacket | None = ..., + want_config_id: builtins.int = ..., + disconnect: builtins.bool = ..., + xmodemPacket: meshtastic.protobuf.xmodem_pb2.XModem | None = ..., + mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., + heartbeat: global___Heartbeat | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["disconnect", b"disconnect", "heartbeat", b"heartbeat", "mqttClientProxyMessage", b"mqttClientProxyMessage", "packet", b"packet", "payload_variant", b"payload_variant", "want_config_id", b"want_config_id", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["disconnect", b"disconnect", "heartbeat", b"heartbeat", "mqttClientProxyMessage", b"mqttClientProxyMessage", "packet", b"packet", "payload_variant", b"payload_variant", "want_config_id", b"want_config_id", "xmodemPacket", b"xmodemPacket"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "want_config_id", "disconnect", "xmodemPacket", "mqttClientProxyMessage", "heartbeat"] | None: ... + +global___ToRadio = ToRadio + +@typing.final +class Compressed(google.protobuf.message.Message): + """ + Compressed message payload + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PORTNUM_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + portnum: meshtastic.protobuf.portnums_pb2.PortNum.ValueType + """ + PortNum to determine the how to handle the compressed payload. + """ + data: builtins.bytes + """ + Compressed data. + """ + def __init__( + self, + *, + portnum: meshtastic.protobuf.portnums_pb2.PortNum.ValueType = ..., + data: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["data", b"data", "portnum", b"portnum"]) -> None: ... + +global___Compressed = Compressed + +@typing.final +class NeighborInfo(google.protobuf.message.Message): + """ + Full info on edges for a single node + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NODE_ID_FIELD_NUMBER: builtins.int + LAST_SENT_BY_ID_FIELD_NUMBER: builtins.int + NODE_BROADCAST_INTERVAL_SECS_FIELD_NUMBER: builtins.int + NEIGHBORS_FIELD_NUMBER: builtins.int + node_id: builtins.int + """ + The node ID of the node sending info on its neighbors + """ + last_sent_by_id: builtins.int + """ + Field to pass neighbor info for the next sending cycle + """ + node_broadcast_interval_secs: builtins.int + """ + Broadcast interval of the represented node (in seconds) + """ + @property + def neighbors(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Neighbor]: + """ + The list of out edges from this node + """ + + def __init__( + self, + *, + node_id: builtins.int = ..., + last_sent_by_id: builtins.int = ..., + node_broadcast_interval_secs: builtins.int = ..., + neighbors: collections.abc.Iterable[global___Neighbor] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["last_sent_by_id", b"last_sent_by_id", "neighbors", b"neighbors", "node_broadcast_interval_secs", b"node_broadcast_interval_secs", "node_id", b"node_id"]) -> None: ... + +global___NeighborInfo = NeighborInfo + +@typing.final +class Neighbor(google.protobuf.message.Message): + """ + A single edge in the mesh + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NODE_ID_FIELD_NUMBER: builtins.int + SNR_FIELD_NUMBER: builtins.int + LAST_RX_TIME_FIELD_NUMBER: builtins.int + NODE_BROADCAST_INTERVAL_SECS_FIELD_NUMBER: builtins.int + node_id: builtins.int + """ + Node ID of neighbor + """ + snr: builtins.float + """ + SNR of last heard message + """ + last_rx_time: builtins.int + """ + Reception time (in secs since 1970) of last message that was last sent by this ID. + Note: this is for local storage only and will not be sent out over the mesh. + """ + node_broadcast_interval_secs: builtins.int + """ + Broadcast interval of this neighbor (in seconds). + Note: this is for local storage only and will not be sent out over the mesh. + """ + def __init__( + self, + *, + node_id: builtins.int = ..., + snr: builtins.float = ..., + last_rx_time: builtins.int = ..., + node_broadcast_interval_secs: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["last_rx_time", b"last_rx_time", "node_broadcast_interval_secs", b"node_broadcast_interval_secs", "node_id", b"node_id", "snr", b"snr"]) -> None: ... + +global___Neighbor = Neighbor + +@typing.final +class DeviceMetadata(google.protobuf.message.Message): + """ + Device metadata response + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIRMWARE_VERSION_FIELD_NUMBER: builtins.int + DEVICE_STATE_VERSION_FIELD_NUMBER: builtins.int + CANSHUTDOWN_FIELD_NUMBER: builtins.int + HASWIFI_FIELD_NUMBER: builtins.int + HASBLUETOOTH_FIELD_NUMBER: builtins.int + HASETHERNET_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + POSITION_FLAGS_FIELD_NUMBER: builtins.int + HW_MODEL_FIELD_NUMBER: builtins.int + HASREMOTEHARDWARE_FIELD_NUMBER: builtins.int + firmware_version: builtins.str + """ + Device firmware version string + """ + device_state_version: builtins.int + """ + Device state version + """ + canShutdown: builtins.bool + """ + Indicates whether the device can shutdown CPU natively or via power management chip + """ + hasWifi: builtins.bool + """ + Indicates that the device has native wifi capability + """ + hasBluetooth: builtins.bool + """ + Indicates that the device has native bluetooth capability + """ + hasEthernet: builtins.bool + """ + Indicates that the device has an ethernet peripheral + """ + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType + """ + Indicates that the device's role in the mesh + """ + position_flags: builtins.int + """ + Indicates the device's current enabled position flags + """ + hw_model: global___HardwareModel.ValueType + """ + Device hardware model + """ + hasRemoteHardware: builtins.bool + """ + Has Remote Hardware enabled + """ + def __init__( + self, + *, + firmware_version: builtins.str = ..., + device_state_version: builtins.int = ..., + canShutdown: builtins.bool = ..., + hasWifi: builtins.bool = ..., + hasBluetooth: builtins.bool = ..., + hasEthernet: builtins.bool = ..., + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ..., + position_flags: builtins.int = ..., + hw_model: global___HardwareModel.ValueType = ..., + hasRemoteHardware: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["canShutdown", b"canShutdown", "device_state_version", b"device_state_version", "firmware_version", b"firmware_version", "hasBluetooth", b"hasBluetooth", "hasEthernet", b"hasEthernet", "hasRemoteHardware", b"hasRemoteHardware", "hasWifi", b"hasWifi", "hw_model", b"hw_model", "position_flags", b"position_flags", "role", b"role"]) -> None: ... + +global___DeviceMetadata = DeviceMetadata + +@typing.final +class Heartbeat(google.protobuf.message.Message): + """ + A heartbeat message is sent to the node from the client to keep the connection alive. + This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___Heartbeat = Heartbeat + +@typing.final +class NodeRemoteHardwarePin(google.protobuf.message.Message): + """ + RemoteHardwarePins associated with a node + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NODE_NUM_FIELD_NUMBER: builtins.int + PIN_FIELD_NUMBER: builtins.int + node_num: builtins.int + """ + The node_num exposing the available gpio pin + """ + @property + def pin(self) -> meshtastic.protobuf.module_config_pb2.RemoteHardwarePin: + """ + The the available gpio pin for usage with RemoteHardware module + """ + + def __init__( + self, + *, + node_num: builtins.int = ..., + pin: meshtastic.protobuf.module_config_pb2.RemoteHardwarePin | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["pin", b"pin"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["node_num", b"node_num", "pin", b"pin"]) -> None: ... + +global___NodeRemoteHardwarePin = NodeRemoteHardwarePin + +@typing.final +class ChunkedPayload(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAYLOAD_ID_FIELD_NUMBER: builtins.int + CHUNK_COUNT_FIELD_NUMBER: builtins.int + CHUNK_INDEX_FIELD_NUMBER: builtins.int + PAYLOAD_CHUNK_FIELD_NUMBER: builtins.int + payload_id: builtins.int + """ + The ID of the entire payload + """ + chunk_count: builtins.int + """ + The total number of chunks in the payload + """ + chunk_index: builtins.int + """ + The current chunk index in the total + """ + payload_chunk: builtins.bytes + """ + The binary data of the current chunk + """ + def __init__( + self, + *, + payload_id: builtins.int = ..., + chunk_count: builtins.int = ..., + chunk_index: builtins.int = ..., + payload_chunk: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["chunk_count", b"chunk_count", "chunk_index", b"chunk_index", "payload_chunk", b"payload_chunk", "payload_id", b"payload_id"]) -> None: ... + +global___ChunkedPayload = ChunkedPayload + +@typing.final +class resend_chunks(google.protobuf.message.Message): + """ + Wrapper message for broken repeated oneof support + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CHUNKS_FIELD_NUMBER: builtins.int + @property + def chunks(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + def __init__( + self, + *, + chunks: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["chunks", b"chunks"]) -> None: ... + +global___resend_chunks = resend_chunks + +@typing.final +class ChunkedPayloadResponse(google.protobuf.message.Message): + """ + Responses to a ChunkedPayload request + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAYLOAD_ID_FIELD_NUMBER: builtins.int + REQUEST_TRANSFER_FIELD_NUMBER: builtins.int + ACCEPT_TRANSFER_FIELD_NUMBER: builtins.int + RESEND_CHUNKS_FIELD_NUMBER: builtins.int + payload_id: builtins.int + """ + The ID of the entire payload + """ + request_transfer: builtins.bool + """ + Request to transfer chunked payload + """ + accept_transfer: builtins.bool + """ + Accept the transfer chunked payload + """ + @property + def resend_chunks(self) -> global___resend_chunks: + """ + Request missing indexes in the chunked payload + """ + + def __init__( + self, + *, + payload_id: builtins.int = ..., + request_transfer: builtins.bool = ..., + accept_transfer: builtins.bool = ..., + resend_chunks: global___resend_chunks | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["accept_transfer", b"accept_transfer", "payload_variant", b"payload_variant", "request_transfer", b"request_transfer", "resend_chunks", b"resend_chunks"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["accept_transfer", b"accept_transfer", "payload_id", b"payload_id", "payload_variant", b"payload_variant", "request_transfer", b"request_transfer", "resend_chunks", b"resend_chunks"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["request_transfer", "accept_transfer", "resend_chunks"] | None: ... + +global___ChunkedPayloadResponse = ChunkedPayloadResponse diff --git a/meshtastic/protobuf/module_config_pb2.py b/meshtastic/protobuf/module_config_pb2.py new file mode 100644 index 0000000..b75bbfa --- /dev/null +++ b/meshtastic/protobuf/module_config_pb2.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/module_config.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import 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/module_config.proto\x12\x13meshtastic.protobuf\"\x90$\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1aN\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1a>\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x1a\xd2\x01\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12 \n\x18\x64\x65tection_triggered_high\x18\x07 \x01(\x08\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xf6\x04\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"U\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x84\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x1a@\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x1a\xe6\x02\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x1a\xf1\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x0f\n\x07\x65nabled\x18\t \x01(\x08\x12\x1a\n\x12\x61llow_input_source\x18\n \x01(\t\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\rB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42g\n\x13\x63om.geeksville.meshB\x12ModuleConfigProtosZ\"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.module_config_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\022ModuleConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=4802 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=4875 + _globals['_MODULECONFIG']._serialized_start=65 + _globals['_MODULECONFIG']._serialized_end=4689 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1080 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1393 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1395 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_end=1473 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_start=1476 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_end=1615 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_start=1617 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_end=1679 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_start=1682 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_end=1892 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_start=1895 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_end=2260 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_start=2093 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_end=2260 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2262 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=2380 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=2383 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3013 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=2660 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=2926 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=2928 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3013 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3016 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=3377 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=3380 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=3512 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=3514 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=3578 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=3581 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=3939 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=3942 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=4567 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=4468 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=4567 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=4569 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=4670 + _globals['_REMOTEHARDWAREPIN']._serialized_start=4691 + _globals['_REMOTEHARDWAREPIN']._serialized_end=4800 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/module_config_pb2.pyi b/meshtastic/protobuf/module_config_pb2.pyi new file mode 100644 index 0000000..eb4f986 --- /dev/null +++ b/meshtastic/protobuf/module_config_pb2.pyi @@ -0,0 +1,1200 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +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 _RemoteHardwarePinType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _RemoteHardwarePinTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RemoteHardwarePinType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNKNOWN: _RemoteHardwarePinType.ValueType # 0 + """ + Unset/unused + """ + DIGITAL_READ: _RemoteHardwarePinType.ValueType # 1 + """ + GPIO pin can be read (if it is high / low) + """ + DIGITAL_WRITE: _RemoteHardwarePinType.ValueType # 2 + """ + GPIO pin can be written to (high / low) + """ + +class RemoteHardwarePinType(_RemoteHardwarePinType, metaclass=_RemoteHardwarePinTypeEnumTypeWrapper): ... + +UNKNOWN: RemoteHardwarePinType.ValueType # 0 +""" +Unset/unused +""" +DIGITAL_READ: RemoteHardwarePinType.ValueType # 1 +""" +GPIO pin can be read (if it is high / low) +""" +DIGITAL_WRITE: RemoteHardwarePinType.ValueType # 2 +""" +GPIO pin can be written to (high / low) +""" +global___RemoteHardwarePinType = RemoteHardwarePinType + +@typing.final +class ModuleConfig(google.protobuf.message.Message): + """ + Module Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class MQTTConfig(google.protobuf.message.Message): + """ + MQTT Client Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + ADDRESS_FIELD_NUMBER: builtins.int + USERNAME_FIELD_NUMBER: builtins.int + PASSWORD_FIELD_NUMBER: builtins.int + ENCRYPTION_ENABLED_FIELD_NUMBER: builtins.int + JSON_ENABLED_FIELD_NUMBER: builtins.int + TLS_ENABLED_FIELD_NUMBER: builtins.int + ROOT_FIELD_NUMBER: builtins.int + PROXY_TO_CLIENT_ENABLED_FIELD_NUMBER: builtins.int + MAP_REPORTING_ENABLED_FIELD_NUMBER: builtins.int + MAP_REPORT_SETTINGS_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + If a meshtastic node is able to reach the internet it will normally attempt to gateway any channels that are marked as + is_uplink_enabled or is_downlink_enabled. + """ + address: builtins.str + """ + The server to use for our MQTT global message gateway feature. + If not set, the default server will be used + """ + username: builtins.str + """ + MQTT username to use (most useful for a custom MQTT server). + If using a custom server, this will be honoured even if empty. + If using the default server, this will only be honoured if set, otherwise the device will use the default username + """ + password: builtins.str + """ + MQTT password to use (most useful for a custom MQTT server). + If using a custom server, this will be honoured even if empty. + If using the default server, this will only be honoured if set, otherwise the device will use the default password + """ + encryption_enabled: builtins.bool + """ + Whether to send encrypted or decrypted packets to MQTT. + This parameter is only honoured if you also set server + (the default official mqtt.meshtastic.org server can handle encrypted packets) + Decrypted packets may be useful for external systems that want to consume meshtastic packets + """ + json_enabled: builtins.bool + """ + Whether to send / consume json packets on MQTT + """ + tls_enabled: builtins.bool + """ + If true, we attempt to establish a secure connection using TLS + """ + root: builtins.str + """ + The root topic to use for MQTT messages. Default is "msh". + This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs + """ + proxy_to_client_enabled: builtins.bool + """ + If true, we can use the connected phone / client to proxy messages to MQTT instead of a direct connection + """ + map_reporting_enabled: builtins.bool + """ + If true, we will periodically report unencrypted information about our node to a map via MQTT + """ + @property + def map_report_settings(self) -> global___ModuleConfig.MapReportSettings: + """ + Settings for reporting information about our node to a map via MQTT + """ + + def __init__( + self, + *, + enabled: builtins.bool = ..., + address: builtins.str = ..., + username: builtins.str = ..., + password: builtins.str = ..., + encryption_enabled: builtins.bool = ..., + json_enabled: builtins.bool = ..., + tls_enabled: builtins.bool = ..., + root: builtins.str = ..., + proxy_to_client_enabled: builtins.bool = ..., + map_reporting_enabled: builtins.bool = ..., + map_report_settings: global___ModuleConfig.MapReportSettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["map_report_settings", b"map_report_settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "enabled", b"enabled", "encryption_enabled", b"encryption_enabled", "json_enabled", b"json_enabled", "map_report_settings", b"map_report_settings", "map_reporting_enabled", b"map_reporting_enabled", "password", b"password", "proxy_to_client_enabled", b"proxy_to_client_enabled", "root", b"root", "tls_enabled", b"tls_enabled", "username", b"username"]) -> None: ... + + @typing.final + class MapReportSettings(google.protobuf.message.Message): + """ + Settings for reporting unencrypted information about our node to a map via MQTT + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PUBLISH_INTERVAL_SECS_FIELD_NUMBER: builtins.int + POSITION_PRECISION_FIELD_NUMBER: builtins.int + publish_interval_secs: builtins.int + """ + How often we should report our info to the map (in seconds) + """ + position_precision: builtins.int + """ + Bits of precision for the location sent (default of 32 is full precision). + """ + def __init__( + self, + *, + publish_interval_secs: builtins.int = ..., + position_precision: builtins.int = ..., + ) -> 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): + """ + RemoteHardwareModule Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + ALLOW_UNDEFINED_PIN_ACCESS_FIELD_NUMBER: builtins.int + AVAILABLE_PINS_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Whether the Module is enabled + """ + allow_undefined_pin_access: builtins.bool + """ + Whether the Module allows consumers to read / write to pins not defined in available_pins + """ + @property + def available_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___RemoteHardwarePin]: + """ + Exposes the available pins to the mesh for reading and writing + """ + + def __init__( + self, + *, + enabled: builtins.bool = ..., + allow_undefined_pin_access: builtins.bool = ..., + available_pins: collections.abc.Iterable[global___RemoteHardwarePin] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["allow_undefined_pin_access", b"allow_undefined_pin_access", "available_pins", b"available_pins", "enabled", b"enabled"]) -> None: ... + + @typing.final + class NeighborInfoConfig(google.protobuf.message.Message): + """ + NeighborInfoModule Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Whether the Module is enabled + """ + update_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + Neighbor Info to the mesh + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + update_interval: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "update_interval", b"update_interval"]) -> None: ... + + @typing.final + class DetectionSensorConfig(google.protobuf.message.Message): + """ + Detection Sensor Module Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + MINIMUM_BROADCAST_SECS_FIELD_NUMBER: builtins.int + STATE_BROADCAST_SECS_FIELD_NUMBER: builtins.int + SEND_BELL_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + MONITOR_PIN_FIELD_NUMBER: builtins.int + DETECTION_TRIGGERED_HIGH_FIELD_NUMBER: builtins.int + USE_PULLUP_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Whether the Module is enabled + """ + minimum_broadcast_secs: builtins.int + """ + Interval in seconds of how often we can send a message to the mesh when a state change is detected + """ + state_broadcast_secs: builtins.int + """ + Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes + When set to 0, only state changes will be broadcasted + Works as a sort of status heartbeat for peace of mind + """ + send_bell: builtins.bool + """ + Send ASCII bell with alert message + Useful for triggering ext. notification on bell + """ + name: builtins.str + """ + Friendly name used to format message sent to mesh + Example: A name "Motion" would result in a message "Motion detected" + Maximum length of 20 characters + """ + monitor_pin: builtins.int + """ + GPIO pin to monitor for state changes + """ + detection_triggered_high: builtins.bool + """ + Whether or not the GPIO pin state detection is triggered on HIGH (1) + Otherwise LOW (0) + """ + use_pullup: builtins.bool + """ + Whether or not use INPUT_PULLUP mode for GPIO pin + Only applicable if the board uses pull-up resistors on the pin + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + minimum_broadcast_secs: builtins.int = ..., + state_broadcast_secs: builtins.int = ..., + send_bell: builtins.bool = ..., + name: builtins.str = ..., + monitor_pin: builtins.int = ..., + detection_triggered_high: builtins.bool = ..., + use_pullup: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["detection_triggered_high", b"detection_triggered_high", "enabled", b"enabled", "minimum_broadcast_secs", b"minimum_broadcast_secs", "monitor_pin", b"monitor_pin", "name", b"name", "send_bell", b"send_bell", "state_broadcast_secs", b"state_broadcast_secs", "use_pullup", b"use_pullup"]) -> None: ... + + @typing.final + class AudioConfig(google.protobuf.message.Message): + """ + Audio Config for codec2 voice + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Audio_Baud: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _Audio_BaudEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.AudioConfig._Audio_Baud.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CODEC2_DEFAULT: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 0 + CODEC2_3200: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 1 + CODEC2_2400: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 2 + CODEC2_1600: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 3 + CODEC2_1400: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 4 + CODEC2_1300: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 5 + CODEC2_1200: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 6 + CODEC2_700: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 7 + CODEC2_700B: ModuleConfig.AudioConfig._Audio_Baud.ValueType # 8 + + class Audio_Baud(_Audio_Baud, metaclass=_Audio_BaudEnumTypeWrapper): + """ + Baudrate for codec2 voice + """ + + CODEC2_DEFAULT: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 0 + CODEC2_3200: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 1 + CODEC2_2400: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 2 + CODEC2_1600: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 3 + CODEC2_1400: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 4 + CODEC2_1300: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 5 + CODEC2_1200: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 6 + CODEC2_700: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 7 + CODEC2_700B: ModuleConfig.AudioConfig.Audio_Baud.ValueType # 8 + + CODEC2_ENABLED_FIELD_NUMBER: builtins.int + PTT_PIN_FIELD_NUMBER: builtins.int + BITRATE_FIELD_NUMBER: builtins.int + I2S_WS_FIELD_NUMBER: builtins.int + I2S_SD_FIELD_NUMBER: builtins.int + I2S_DIN_FIELD_NUMBER: builtins.int + I2S_SCK_FIELD_NUMBER: builtins.int + codec2_enabled: builtins.bool + """ + Whether Audio is enabled + """ + ptt_pin: builtins.int + """ + PTT Pin + """ + bitrate: global___ModuleConfig.AudioConfig.Audio_Baud.ValueType + """ + The audio sample rate to use for codec2 + """ + i2s_ws: builtins.int + """ + I2S Word Select + """ + i2s_sd: builtins.int + """ + I2S Data IN + """ + i2s_din: builtins.int + """ + I2S Data OUT + """ + i2s_sck: builtins.int + """ + I2S Clock + """ + def __init__( + self, + *, + codec2_enabled: builtins.bool = ..., + ptt_pin: builtins.int = ..., + bitrate: global___ModuleConfig.AudioConfig.Audio_Baud.ValueType = ..., + i2s_ws: builtins.int = ..., + i2s_sd: builtins.int = ..., + i2s_din: builtins.int = ..., + i2s_sck: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["bitrate", b"bitrate", "codec2_enabled", b"codec2_enabled", "i2s_din", b"i2s_din", "i2s_sck", b"i2s_sck", "i2s_sd", b"i2s_sd", "i2s_ws", b"i2s_ws", "ptt_pin", b"ptt_pin"]) -> None: ... + + @typing.final + class PaxcounterConfig(google.protobuf.message.Message): + """ + Config for the Paxcounter Module + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + PAXCOUNTER_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + WIFI_THRESHOLD_FIELD_NUMBER: builtins.int + BLE_THRESHOLD_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Enable the Paxcounter Module + """ + paxcounter_update_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + metrics to the mesh + """ + wifi_threshold: builtins.int + """ + WiFi RSSI threshold. Defaults to -80 + """ + ble_threshold: builtins.int + """ + BLE RSSI threshold. Defaults to -80 + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + paxcounter_update_interval: builtins.int = ..., + wifi_threshold: builtins.int = ..., + ble_threshold: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ble_threshold", b"ble_threshold", "enabled", b"enabled", "paxcounter_update_interval", b"paxcounter_update_interval", "wifi_threshold", b"wifi_threshold"]) -> None: ... + + @typing.final + class SerialConfig(google.protobuf.message.Message): + """ + Serial Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Serial_Baud: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _Serial_BaudEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.SerialConfig._Serial_Baud.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + BAUD_DEFAULT: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 0 + BAUD_110: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 1 + BAUD_300: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 2 + BAUD_600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 3 + BAUD_1200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 4 + BAUD_2400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 5 + BAUD_4800: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 6 + BAUD_9600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 7 + BAUD_19200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 8 + BAUD_38400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 9 + BAUD_57600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 10 + BAUD_115200: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 11 + BAUD_230400: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 12 + BAUD_460800: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 13 + BAUD_576000: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 14 + BAUD_921600: ModuleConfig.SerialConfig._Serial_Baud.ValueType # 15 + + class Serial_Baud(_Serial_Baud, metaclass=_Serial_BaudEnumTypeWrapper): + """ + TODO: REPLACE + """ + + BAUD_DEFAULT: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 0 + BAUD_110: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 1 + BAUD_300: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 2 + BAUD_600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 3 + BAUD_1200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 4 + BAUD_2400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 5 + BAUD_4800: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 6 + BAUD_9600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 7 + BAUD_19200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 8 + BAUD_38400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 9 + BAUD_57600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 10 + BAUD_115200: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 11 + BAUD_230400: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 12 + BAUD_460800: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 13 + BAUD_576000: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 14 + BAUD_921600: ModuleConfig.SerialConfig.Serial_Baud.ValueType # 15 + + class _Serial_Mode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _Serial_ModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.SerialConfig._Serial_Mode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DEFAULT: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 0 + SIMPLE: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 1 + PROTO: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 2 + TEXTMSG: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 3 + NMEA: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 4 + CALTOPO: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 5 + """NMEA messages specifically tailored for CalTopo""" + + class Serial_Mode(_Serial_Mode, metaclass=_Serial_ModeEnumTypeWrapper): + """ + TODO: REPLACE + """ + + DEFAULT: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 0 + SIMPLE: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 1 + PROTO: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 2 + TEXTMSG: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 3 + NMEA: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 4 + CALTOPO: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 5 + """NMEA messages specifically tailored for CalTopo""" + + ENABLED_FIELD_NUMBER: builtins.int + ECHO_FIELD_NUMBER: builtins.int + RXD_FIELD_NUMBER: builtins.int + TXD_FIELD_NUMBER: builtins.int + BAUD_FIELD_NUMBER: builtins.int + TIMEOUT_FIELD_NUMBER: builtins.int + MODE_FIELD_NUMBER: builtins.int + OVERRIDE_CONSOLE_SERIAL_PORT_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Preferences for the SerialModule + """ + echo: builtins.bool + """ + TODO: REPLACE + """ + rxd: builtins.int + """ + RX pin (should match Arduino gpio pin number) + """ + txd: builtins.int + """ + TX pin (should match Arduino gpio pin number) + """ + baud: global___ModuleConfig.SerialConfig.Serial_Baud.ValueType + """ + Serial baud rate + """ + timeout: builtins.int + """ + TODO: REPLACE + """ + mode: global___ModuleConfig.SerialConfig.Serial_Mode.ValueType + """ + Mode for serial module operation + """ + override_console_serial_port: builtins.bool + """ + Overrides the platform's defacto Serial port instance to use with Serial module config settings + This is currently only usable in output modes like NMEA / CalTopo and may behave strangely or not work at all in other modes + Existing logging over the Serial Console will still be present + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + echo: builtins.bool = ..., + rxd: builtins.int = ..., + txd: builtins.int = ..., + baud: global___ModuleConfig.SerialConfig.Serial_Baud.ValueType = ..., + timeout: builtins.int = ..., + mode: global___ModuleConfig.SerialConfig.Serial_Mode.ValueType = ..., + override_console_serial_port: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["baud", b"baud", "echo", b"echo", "enabled", b"enabled", "mode", b"mode", "override_console_serial_port", b"override_console_serial_port", "rxd", b"rxd", "timeout", b"timeout", "txd", b"txd"]) -> None: ... + + @typing.final + class ExternalNotificationConfig(google.protobuf.message.Message): + """ + External Notifications Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + OUTPUT_MS_FIELD_NUMBER: builtins.int + OUTPUT_FIELD_NUMBER: builtins.int + OUTPUT_VIBRA_FIELD_NUMBER: builtins.int + OUTPUT_BUZZER_FIELD_NUMBER: builtins.int + ACTIVE_FIELD_NUMBER: builtins.int + ALERT_MESSAGE_FIELD_NUMBER: builtins.int + ALERT_MESSAGE_VIBRA_FIELD_NUMBER: builtins.int + ALERT_MESSAGE_BUZZER_FIELD_NUMBER: builtins.int + ALERT_BELL_FIELD_NUMBER: builtins.int + ALERT_BELL_VIBRA_FIELD_NUMBER: builtins.int + ALERT_BELL_BUZZER_FIELD_NUMBER: builtins.int + USE_PWM_FIELD_NUMBER: builtins.int + NAG_TIMEOUT_FIELD_NUMBER: builtins.int + USE_I2S_AS_BUZZER_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Enable the ExternalNotificationModule + """ + output_ms: builtins.int + """ + When using in On/Off mode, keep the output on for this many + milliseconds. Default 1000ms (1 second). + """ + output: builtins.int + """ + Define the output pin GPIO setting Defaults to + EXT_NOTIFY_OUT if set for the board. + In standalone devices this pin should drive the LED to match the UI. + """ + output_vibra: builtins.int + """ + Optional: Define a secondary output pin for a vibra motor + This is used in standalone devices to match the UI. + """ + output_buzzer: builtins.int + """ + Optional: Define a tertiary output pin for an active buzzer + This is used in standalone devices to to match the UI. + """ + active: builtins.bool + """ + IF this is true, the 'output' Pin will be pulled active high, false + means active low. + """ + alert_message: builtins.bool + """ + True: Alert when a text message arrives (output) + """ + alert_message_vibra: builtins.bool + """ + True: Alert when a text message arrives (output_vibra) + """ + alert_message_buzzer: builtins.bool + """ + True: Alert when a text message arrives (output_buzzer) + """ + alert_bell: builtins.bool + """ + True: Alert when the bell character is received (output) + """ + alert_bell_vibra: builtins.bool + """ + True: Alert when the bell character is received (output_vibra) + """ + alert_bell_buzzer: builtins.bool + """ + True: Alert when the bell character is received (output_buzzer) + """ + use_pwm: builtins.bool + """ + use a PWM output instead of a simple on/off output. This will ignore + the 'output', 'output_ms' and 'active' settings and use the + device.buzzer_gpio instead. + """ + nag_timeout: builtins.int + """ + The notification will toggle with 'output_ms' for this time of seconds. + Default is 0 which means don't repeat at all. 60 would mean blink + and/or beep for 60 seconds + """ + use_i2s_as_buzzer: builtins.bool + """ + When true, enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer + T-Watch S3 and T-Deck for example have this capability + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + output_ms: builtins.int = ..., + output: builtins.int = ..., + output_vibra: builtins.int = ..., + output_buzzer: builtins.int = ..., + active: builtins.bool = ..., + alert_message: builtins.bool = ..., + alert_message_vibra: builtins.bool = ..., + alert_message_buzzer: builtins.bool = ..., + alert_bell: builtins.bool = ..., + alert_bell_vibra: builtins.bool = ..., + alert_bell_buzzer: builtins.bool = ..., + use_pwm: builtins.bool = ..., + nag_timeout: builtins.int = ..., + use_i2s_as_buzzer: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["active", b"active", "alert_bell", b"alert_bell", "alert_bell_buzzer", b"alert_bell_buzzer", "alert_bell_vibra", b"alert_bell_vibra", "alert_message", b"alert_message", "alert_message_buzzer", b"alert_message_buzzer", "alert_message_vibra", b"alert_message_vibra", "enabled", b"enabled", "nag_timeout", b"nag_timeout", "output", b"output", "output_buzzer", b"output_buzzer", "output_ms", b"output_ms", "output_vibra", b"output_vibra", "use_i2s_as_buzzer", b"use_i2s_as_buzzer", "use_pwm", b"use_pwm"]) -> None: ... + + @typing.final + class StoreForwardConfig(google.protobuf.message.Message): + """ + Store and Forward Module Config + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + HEARTBEAT_FIELD_NUMBER: builtins.int + RECORDS_FIELD_NUMBER: builtins.int + HISTORY_RETURN_MAX_FIELD_NUMBER: builtins.int + HISTORY_RETURN_WINDOW_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Enable the Store and Forward Module + """ + heartbeat: builtins.bool + """ + TODO: REPLACE + """ + records: builtins.int + """ + TODO: REPLACE + """ + history_return_max: builtins.int + """ + TODO: REPLACE + """ + history_return_window: builtins.int + """ + TODO: REPLACE + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + heartbeat: builtins.bool = ..., + records: builtins.int = ..., + history_return_max: builtins.int = ..., + history_return_window: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "heartbeat", b"heartbeat", "history_return_max", b"history_return_max", "history_return_window", b"history_return_window", "records", b"records"]) -> None: ... + + @typing.final + class RangeTestConfig(google.protobuf.message.Message): + """ + Preferences for the RangeTestModule + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + SENDER_FIELD_NUMBER: builtins.int + SAVE_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Enable the Range Test Module + """ + sender: builtins.int + """ + Send out range test messages from this node + """ + save: builtins.bool + """ + Bool value indicating that this node should save a RangeTest.csv file. + ESP32 Only + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + sender: builtins.int = ..., + save: builtins.bool = ..., + ) -> 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): + """ + Configuration for both device and environment metrics + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DEVICE_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + ENVIRONMENT_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + ENVIRONMENT_MEASUREMENT_ENABLED_FIELD_NUMBER: builtins.int + ENVIRONMENT_SCREEN_ENABLED_FIELD_NUMBER: builtins.int + ENVIRONMENT_DISPLAY_FAHRENHEIT_FIELD_NUMBER: builtins.int + AIR_QUALITY_ENABLED_FIELD_NUMBER: builtins.int + AIR_QUALITY_INTERVAL_FIELD_NUMBER: builtins.int + POWER_MEASUREMENT_ENABLED_FIELD_NUMBER: builtins.int + POWER_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int + POWER_SCREEN_ENABLED_FIELD_NUMBER: builtins.int + device_update_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + device metrics to the mesh + """ + environment_update_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + environment measurements to the mesh + """ + environment_measurement_enabled: builtins.bool + """ + Preferences for the Telemetry Module (Environment) + Enable/Disable the telemetry measurement module measurement collection + """ + environment_screen_enabled: builtins.bool + """ + Enable/Disable the telemetry measurement module on-device display + """ + environment_display_fahrenheit: builtins.bool + """ + We'll always read the sensor in Celsius, but sometimes we might want to + display the results in Fahrenheit as a "user preference". + """ + air_quality_enabled: builtins.bool + """ + Enable/Disable the air quality metrics + """ + air_quality_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + air quality metrics to the mesh + """ + power_measurement_enabled: builtins.bool + """ + Interval in seconds of how often we should try to send our + air quality metrics to the mesh + """ + power_update_interval: builtins.int + """ + Interval in seconds of how often we should try to send our + air quality metrics to the mesh + """ + power_screen_enabled: builtins.bool + """ + Interval in seconds of how often we should try to send our + air quality metrics to the mesh + """ + def __init__( + self, + *, + device_update_interval: builtins.int = ..., + environment_update_interval: builtins.int = ..., + environment_measurement_enabled: builtins.bool = ..., + environment_screen_enabled: builtins.bool = ..., + environment_display_fahrenheit: builtins.bool = ..., + air_quality_enabled: builtins.bool = ..., + air_quality_interval: builtins.int = ..., + power_measurement_enabled: builtins.bool = ..., + power_update_interval: builtins.int = ..., + power_screen_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_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", "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): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _InputEventChar: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _InputEventCharEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ModuleConfig.CannedMessageConfig._InputEventChar.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NONE: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 0 + """ + TODO: REPLACE + """ + UP: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 17 + """ + TODO: REPLACE + """ + DOWN: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 18 + """ + TODO: REPLACE + """ + LEFT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 19 + """ + TODO: REPLACE + """ + RIGHT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 20 + """ + TODO: REPLACE + """ + SELECT: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 10 + """ + '\\n' + """ + BACK: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 27 + """ + TODO: REPLACE + """ + CANCEL: ModuleConfig.CannedMessageConfig._InputEventChar.ValueType # 24 + """ + TODO: REPLACE + """ + + class InputEventChar(_InputEventChar, metaclass=_InputEventCharEnumTypeWrapper): + """ + TODO: REPLACE + """ + + NONE: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 0 + """ + TODO: REPLACE + """ + UP: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 17 + """ + TODO: REPLACE + """ + DOWN: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 18 + """ + TODO: REPLACE + """ + LEFT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 19 + """ + TODO: REPLACE + """ + RIGHT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 20 + """ + TODO: REPLACE + """ + SELECT: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 10 + """ + '\\n' + """ + BACK: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 27 + """ + TODO: REPLACE + """ + CANCEL: ModuleConfig.CannedMessageConfig.InputEventChar.ValueType # 24 + """ + TODO: REPLACE + """ + + ROTARY1_ENABLED_FIELD_NUMBER: builtins.int + INPUTBROKER_PIN_A_FIELD_NUMBER: builtins.int + INPUTBROKER_PIN_B_FIELD_NUMBER: builtins.int + INPUTBROKER_PIN_PRESS_FIELD_NUMBER: builtins.int + INPUTBROKER_EVENT_CW_FIELD_NUMBER: builtins.int + INPUTBROKER_EVENT_CCW_FIELD_NUMBER: builtins.int + INPUTBROKER_EVENT_PRESS_FIELD_NUMBER: builtins.int + UPDOWN1_ENABLED_FIELD_NUMBER: builtins.int + ENABLED_FIELD_NUMBER: builtins.int + ALLOW_INPUT_SOURCE_FIELD_NUMBER: builtins.int + SEND_BELL_FIELD_NUMBER: builtins.int + rotary1_enabled: builtins.bool + """ + Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. + """ + inputbroker_pin_a: builtins.int + """ + GPIO pin for rotary encoder A port. + """ + inputbroker_pin_b: builtins.int + """ + GPIO pin for rotary encoder B port. + """ + inputbroker_pin_press: builtins.int + """ + GPIO pin for rotary encoder Press port. + """ + inputbroker_event_cw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType + """ + Generate input event on CW of this kind. + """ + inputbroker_event_ccw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType + """ + Generate input event on CCW of this kind. + """ + inputbroker_event_press: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType + """ + Generate input event on Press of this kind. + """ + updown1_enabled: builtins.bool + """ + Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker. + """ + enabled: builtins.bool + """ + Enable/disable CannedMessageModule. + """ + allow_input_source: builtins.str + """ + Input event origin accepted by the canned message module. + Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any" + """ + send_bell: builtins.bool + """ + CannedMessageModule also sends a bell character with the messages. + ExternalNotificationModule can benefit from this feature. + """ + def __init__( + self, + *, + rotary1_enabled: builtins.bool = ..., + inputbroker_pin_a: builtins.int = ..., + inputbroker_pin_b: builtins.int = ..., + inputbroker_pin_press: builtins.int = ..., + inputbroker_event_cw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., + inputbroker_event_ccw: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., + inputbroker_event_press: global___ModuleConfig.CannedMessageConfig.InputEventChar.ValueType = ..., + updown1_enabled: builtins.bool = ..., + enabled: builtins.bool = ..., + allow_input_source: builtins.str = ..., + send_bell: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["allow_input_source", b"allow_input_source", "enabled", b"enabled", "inputbroker_event_ccw", b"inputbroker_event_ccw", "inputbroker_event_cw", b"inputbroker_event_cw", "inputbroker_event_press", b"inputbroker_event_press", "inputbroker_pin_a", b"inputbroker_pin_a", "inputbroker_pin_b", b"inputbroker_pin_b", "inputbroker_pin_press", b"inputbroker_pin_press", "rotary1_enabled", b"rotary1_enabled", "send_bell", b"send_bell", "updown1_enabled", b"updown1_enabled"]) -> None: ... + + @typing.final + class AmbientLightingConfig(google.protobuf.message.Message): + """ + Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. + Initially created for the RAK14001 RGB LED module. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LED_STATE_FIELD_NUMBER: builtins.int + CURRENT_FIELD_NUMBER: builtins.int + RED_FIELD_NUMBER: builtins.int + GREEN_FIELD_NUMBER: builtins.int + BLUE_FIELD_NUMBER: builtins.int + led_state: builtins.bool + """ + Sets LED to on or off. + """ + current: builtins.int + """ + Sets the current for the LED output. Default is 10. + """ + red: builtins.int + """ + Sets the red LED level. Values are 0-255. + """ + green: builtins.int + """ + Sets the green LED level. Values are 0-255. + """ + blue: builtins.int + """ + Sets the blue LED level. Values are 0-255. + """ + def __init__( + self, + *, + led_state: builtins.bool = ..., + current: builtins.int = ..., + red: builtins.int = ..., + green: builtins.int = ..., + blue: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["blue", b"blue", "current", b"current", "green", b"green", "led_state", b"led_state", "red", b"red"]) -> None: ... + + MQTT_FIELD_NUMBER: builtins.int + SERIAL_FIELD_NUMBER: builtins.int + EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int + STORE_FORWARD_FIELD_NUMBER: builtins.int + RANGE_TEST_FIELD_NUMBER: builtins.int + TELEMETRY_FIELD_NUMBER: builtins.int + CANNED_MESSAGE_FIELD_NUMBER: builtins.int + AUDIO_FIELD_NUMBER: builtins.int + REMOTE_HARDWARE_FIELD_NUMBER: builtins.int + NEIGHBOR_INFO_FIELD_NUMBER: builtins.int + AMBIENT_LIGHTING_FIELD_NUMBER: builtins.int + DETECTION_SENSOR_FIELD_NUMBER: builtins.int + PAXCOUNTER_FIELD_NUMBER: builtins.int + @property + def mqtt(self) -> global___ModuleConfig.MQTTConfig: + """ + TODO: REPLACE + """ + + @property + def serial(self) -> global___ModuleConfig.SerialConfig: + """ + TODO: REPLACE + """ + + @property + def external_notification(self) -> global___ModuleConfig.ExternalNotificationConfig: + """ + TODO: REPLACE + """ + + @property + def store_forward(self) -> global___ModuleConfig.StoreForwardConfig: + """ + TODO: REPLACE + """ + + @property + def range_test(self) -> global___ModuleConfig.RangeTestConfig: + """ + TODO: REPLACE + """ + + @property + def telemetry(self) -> global___ModuleConfig.TelemetryConfig: + """ + TODO: REPLACE + """ + + @property + def canned_message(self) -> global___ModuleConfig.CannedMessageConfig: + """ + TODO: REPLACE + """ + + @property + def audio(self) -> global___ModuleConfig.AudioConfig: + """ + TODO: REPLACE + """ + + @property + def remote_hardware(self) -> global___ModuleConfig.RemoteHardwareConfig: + """ + TODO: REPLACE + """ + + @property + def neighbor_info(self) -> global___ModuleConfig.NeighborInfoConfig: + """ + TODO: REPLACE + """ + + @property + def ambient_lighting(self) -> global___ModuleConfig.AmbientLightingConfig: + """ + TODO: REPLACE + """ + + @property + def detection_sensor(self) -> global___ModuleConfig.DetectionSensorConfig: + """ + TODO: REPLACE + """ + + @property + def paxcounter(self) -> global___ModuleConfig.PaxcounterConfig: + """ + TODO: REPLACE + """ + + def __init__( + self, + *, + mqtt: global___ModuleConfig.MQTTConfig | None = ..., + serial: global___ModuleConfig.SerialConfig | None = ..., + external_notification: global___ModuleConfig.ExternalNotificationConfig | None = ..., + store_forward: global___ModuleConfig.StoreForwardConfig | None = ..., + range_test: global___ModuleConfig.RangeTestConfig | None = ..., + telemetry: global___ModuleConfig.TelemetryConfig | None = ..., + canned_message: global___ModuleConfig.CannedMessageConfig | None = ..., + audio: global___ModuleConfig.AudioConfig | None = ..., + remote_hardware: global___ModuleConfig.RemoteHardwareConfig | None = ..., + neighbor_info: global___ModuleConfig.NeighborInfoConfig | None = ..., + ambient_lighting: global___ModuleConfig.AmbientLightingConfig | None = ..., + detection_sensor: global___ModuleConfig.DetectionSensorConfig | None = ..., + paxcounter: global___ModuleConfig.PaxcounterConfig | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter"] | None: ... + +global___ModuleConfig = ModuleConfig + +@typing.final +class RemoteHardwarePin(google.protobuf.message.Message): + """ + A GPIO pin definition for remote hardware module + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GPIO_PIN_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + gpio_pin: builtins.int + """ + GPIO Pin number (must match Arduino) + """ + name: builtins.str + """ + Name for the GPIO pin (i.e. Front gate, mailbox, etc) + """ + type: global___RemoteHardwarePinType.ValueType + """ + Type of GPIO access available to consumers on the mesh + """ + def __init__( + self, + *, + gpio_pin: builtins.int = ..., + name: builtins.str = ..., + type: global___RemoteHardwarePinType.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["gpio_pin", b"gpio_pin", "name", b"name", "type", b"type"]) -> None: ... + +global___RemoteHardwarePin = RemoteHardwarePin diff --git a/meshtastic/protobuf/mqtt_pb2.py b/meshtastic/protobuf/mqtt_pb2.py new file mode 100644 index 0000000..8286250 --- /dev/null +++ b/meshtastic/protobuf/mqtt_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/mqtt.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 meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2 +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\"\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\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=710 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mqtt_pb2.pyi b/meshtastic/protobuf/mqtt_pb2.pyi new file mode 100644 index 0000000..7c03e6d --- /dev/null +++ b/meshtastic/protobuf/mqtt_pb2.pyi @@ -0,0 +1,148 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import meshtastic.protobuf.config_pb2 +import meshtastic.protobuf.mesh_pb2 +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class ServiceEnvelope(google.protobuf.message.Message): + """ + This message wraps a MeshPacket with extra metadata about the sender and how it arrived. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PACKET_FIELD_NUMBER: builtins.int + CHANNEL_ID_FIELD_NUMBER: builtins.int + GATEWAY_ID_FIELD_NUMBER: builtins.int + channel_id: builtins.str + """ + The global channel ID it was sent on + """ + gateway_id: builtins.str + """ + The sending gateway node ID. Can we use this to authenticate/prevent fake + nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as + the globally trusted nodenum + """ + @property + def packet(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket: + """ + The (probably encrypted) packet + """ + + def __init__( + self, + *, + packet: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ..., + channel_id: builtins.str = ..., + gateway_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["packet", b"packet"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel_id", b"channel_id", "gateway_id", b"gateway_id", "packet", b"packet"]) -> None: ... + +global___ServiceEnvelope = ServiceEnvelope + +@typing.final +class MapReport(google.protobuf.message.Message): + """ + Information about a node intended to be reported unencrypted to a map using MQTT. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LONG_NAME_FIELD_NUMBER: builtins.int + SHORT_NAME_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + HW_MODEL_FIELD_NUMBER: builtins.int + FIRMWARE_VERSION_FIELD_NUMBER: builtins.int + REGION_FIELD_NUMBER: builtins.int + MODEM_PRESET_FIELD_NUMBER: builtins.int + HAS_DEFAULT_CHANNEL_FIELD_NUMBER: builtins.int + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + ALTITUDE_FIELD_NUMBER: builtins.int + POSITION_PRECISION_FIELD_NUMBER: builtins.int + NUM_ONLINE_LOCAL_NODES_FIELD_NUMBER: builtins.int + long_name: builtins.str + """ + A full name for this user, i.e. "Kevin Hester" + """ + short_name: builtins.str + """ + A VERY short name, ideally two characters. + Suitable for a tiny OLED screen + """ + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType + """ + Role of the node that applies specific settings for a particular use-case + """ + hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType + """ + Hardware model of the node, i.e. T-Beam, Heltec V3, etc... + """ + firmware_version: builtins.str + """ + Device firmware version string + """ + region: meshtastic.protobuf.config_pb2.Config.LoRaConfig.RegionCode.ValueType + """ + The region code for the radio (US, CN, EU433, etc...) + """ + modem_preset: meshtastic.protobuf.config_pb2.Config.LoRaConfig.ModemPreset.ValueType + """ + Modem preset used by the radio (LongFast, MediumSlow, etc...) + """ + has_default_channel: builtins.bool + """ + Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...) + and it uses the default frequency slot given the region and modem preset. + """ + latitude_i: builtins.int + """ + Latitude: multiply by 1e-7 to get degrees in floating point + """ + longitude_i: builtins.int + """ + Longitude: multiply by 1e-7 to get degrees in floating point + """ + altitude: builtins.int + """ + Altitude in meters above MSL + """ + position_precision: builtins.int + """ + Indicates the bits of precision for latitude and longitude set by the sending node + """ + num_online_local_nodes: builtins.int + """ + Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT) + """ + def __init__( + self, + *, + long_name: builtins.str = ..., + short_name: builtins.str = ..., + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ..., + hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType = ..., + firmware_version: builtins.str = ..., + region: meshtastic.protobuf.config_pb2.Config.LoRaConfig.RegionCode.ValueType = ..., + modem_preset: meshtastic.protobuf.config_pb2.Config.LoRaConfig.ModemPreset.ValueType = ..., + has_default_channel: builtins.bool = ..., + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + altitude: builtins.int = ..., + position_precision: builtins.int = ..., + num_online_local_nodes: builtins.int = ..., + ) -> 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 diff --git a/meshtastic/protobuf/paxcount_pb2.py b/meshtastic/protobuf/paxcount_pb2.py new file mode 100644 index 0000000..79353b5 --- /dev/null +++ b/meshtastic/protobuf/paxcount_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/paxcount.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/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\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) diff --git a/meshtastic/protobuf/paxcount_pb2.pyi b/meshtastic/protobuf/paxcount_pb2.pyi new file mode 100644 index 0000000..cc7ed0d --- /dev/null +++ b/meshtastic/protobuf/paxcount_pb2.pyi @@ -0,0 +1,45 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class Paxcount(google.protobuf.message.Message): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + WIFI_FIELD_NUMBER: builtins.int + BLE_FIELD_NUMBER: builtins.int + UPTIME_FIELD_NUMBER: builtins.int + wifi: builtins.int + """ + seen Wifi devices + """ + ble: builtins.int + """ + Seen BLE devices + """ + uptime: builtins.int + """ + Uptime in seconds + """ + def __init__( + self, + *, + wifi: builtins.int = ..., + ble: builtins.int = ..., + uptime: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ble", b"ble", "uptime", b"uptime", "wifi", b"wifi"]) -> None: ... + +global___Paxcount = Paxcount diff --git a/meshtastic/protobuf/portnums_pb2.py b/meshtastic/protobuf/portnums_pb2.py new file mode 100644 index 0000000..bb0cd07 --- /dev/null +++ b/meshtastic/protobuf/portnums_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/portnums.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/portnums.proto\x12\x13meshtastic.protobuf*\x8d\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\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\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\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=585 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/portnums_pb2.pyi b/meshtastic/protobuf/portnums_pb2.pyi new file mode 100644 index 0000000..fda2e89 --- /dev/null +++ b/meshtastic/protobuf/portnums_pb2.pyi @@ -0,0 +1,370 @@ +""" +@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 sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _PortNum: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PortNum.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNKNOWN_APP: _PortNum.ValueType # 0 + """ + Deprecated: do not use in new code (formerly called OPAQUE) + A message sent from a device outside of the mesh, in a form the mesh does not understand + NOTE: This must be 0, because it is documented in IMeshService.aidl to be so + ENCODING: binary undefined + """ + TEXT_MESSAGE_APP: _PortNum.ValueType # 1 + """ + A simple UTF-8 text message, which even the little micros in the mesh + can understand and show on their screen eventually in some circumstances + even signal might send messages in this form (see below) + ENCODING: UTF-8 Plaintext (?) + """ + REMOTE_HARDWARE_APP: _PortNum.ValueType # 2 + """ + Reserved for built-in GPIO/example app. + See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number + ENCODING: Protobuf + """ + POSITION_APP: _PortNum.ValueType # 3 + """ + The built-in position messaging app. + Payload is a Position message. + ENCODING: Protobuf + """ + NODEINFO_APP: _PortNum.ValueType # 4 + """ + The built-in user info app. + Payload is a User message. + ENCODING: Protobuf + """ + ROUTING_APP: _PortNum.ValueType # 5 + """ + Protocol control packets for mesh protocol use. + Payload is a Routing message. + ENCODING: Protobuf + """ + ADMIN_APP: _PortNum.ValueType # 6 + """ + Admin control packets. + Payload is a AdminMessage message. + ENCODING: Protobuf + """ + TEXT_MESSAGE_COMPRESSED_APP: _PortNum.ValueType # 7 + """ + Compressed TEXT_MESSAGE payloads. + ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression + NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed + payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress + any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. + """ + WAYPOINT_APP: _PortNum.ValueType # 8 + """ + Waypoint payloads. + Payload is a Waypoint message. + ENCODING: Protobuf + """ + AUDIO_APP: _PortNum.ValueType # 9 + """ + Audio Payloads. + Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now + ENCODING: codec2 audio frames + NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. + This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. + """ + DETECTION_SENSOR_APP: _PortNum.ValueType # 10 + """ + Same as Text Message but originating from Detection Sensor Module. + NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 + """ + REPLY_APP: _PortNum.ValueType # 32 + """ + Provides a 'ping' service that replies to any packet it receives. + Also serves as a small example module. + ENCODING: ASCII Plaintext + """ + IP_TUNNEL_APP: _PortNum.ValueType # 33 + """ + Used for the python IP tunnel feature + ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. + """ + PAXCOUNTER_APP: _PortNum.ValueType # 34 + """ + Paxcounter lib included in the firmware + ENCODING: protobuf + """ + SERIAL_APP: _PortNum.ValueType # 64 + """ + Provides a hardware serial interface to send and receive from the Meshtastic network. + Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic + network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. + Maximum packet size of 240 bytes. + Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. + ENCODING: binary undefined + """ + STORE_FORWARD_APP: _PortNum.ValueType # 65 + """ + STORE_FORWARD_APP (Work in Progress) + Maintained by Jm Casler (MC Hamster) : jm@casler.org + ENCODING: Protobuf + """ + RANGE_TEST_APP: _PortNum.ValueType # 66 + """ + Optional port for messages for the range test module. + ENCODING: ASCII Plaintext + NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 + """ + TELEMETRY_APP: _PortNum.ValueType # 67 + """ + Provides a format to send and receive telemetry data from the Meshtastic network. + Maintained by Charles Crossan (crossan007) : crossan007@gmail.com + ENCODING: Protobuf + """ + ZPS_APP: _PortNum.ValueType # 68 + """ + Experimental tools for estimating node position without a GPS + Maintained by Github user a-f-G-U-C (a Meshtastic contributor) + Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS + ENCODING: arrays of int64 fields + """ + SIMULATOR_APP: _PortNum.ValueType # 69 + """ + Used to let multiple instances of Linux native applications communicate + as if they did using their LoRa chip. + Maintained by GitHub user GUVWAF. + Project files at https://github.com/GUVWAF/Meshtasticator + ENCODING: Protobuf (?) + """ + TRACEROUTE_APP: _PortNum.ValueType # 70 + """ + Provides a traceroute functionality to show the route a packet towards + a certain destination would take on the mesh. + ENCODING: Protobuf + """ + NEIGHBORINFO_APP: _PortNum.ValueType # 71 + """ + Aggregates edge info for the network by sending out a list of each node's neighbors + ENCODING: Protobuf + """ + ATAK_PLUGIN: _PortNum.ValueType # 72 + """ + ATAK Plugin + Portnum for payloads from the official Meshtastic ATAK plugin + """ + MAP_REPORT_APP: _PortNum.ValueType # 73 + """ + Provides unencrypted information about a node for consumption by a map via MQTT + """ + PRIVATE_APP: _PortNum.ValueType # 256 + """ + Private applications should use portnums >= 256. + To simplify initial development and testing you can use "PRIVATE_APP" + in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) + """ + ATAK_FORWARDER: _PortNum.ValueType # 257 + """ + ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder + ENCODING: libcotshrink + """ + MAX: _PortNum.ValueType # 511 + """ + Currently we limit port nums to no higher than this value + """ + +class PortNum(_PortNum, metaclass=_PortNumEnumTypeWrapper): + """ + For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a + unique 'portnum' for their application. + If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this + master table. + PortNums should be assigned in the following range: + 0-63 Core Meshtastic use, do not use for third party apps + 64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application + 256-511 Use one of these portnums for your private applications that you don't want to register publically + All other values are reserved. + Note: This was formerly a Type enum named 'typ' with the same id # + We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. + This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. + """ + +UNKNOWN_APP: PortNum.ValueType # 0 +""" +Deprecated: do not use in new code (formerly called OPAQUE) +A message sent from a device outside of the mesh, in a form the mesh does not understand +NOTE: This must be 0, because it is documented in IMeshService.aidl to be so +ENCODING: binary undefined +""" +TEXT_MESSAGE_APP: PortNum.ValueType # 1 +""" +A simple UTF-8 text message, which even the little micros in the mesh +can understand and show on their screen eventually in some circumstances +even signal might send messages in this form (see below) +ENCODING: UTF-8 Plaintext (?) +""" +REMOTE_HARDWARE_APP: PortNum.ValueType # 2 +""" +Reserved for built-in GPIO/example app. +See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number +ENCODING: Protobuf +""" +POSITION_APP: PortNum.ValueType # 3 +""" +The built-in position messaging app. +Payload is a Position message. +ENCODING: Protobuf +""" +NODEINFO_APP: PortNum.ValueType # 4 +""" +The built-in user info app. +Payload is a User message. +ENCODING: Protobuf +""" +ROUTING_APP: PortNum.ValueType # 5 +""" +Protocol control packets for mesh protocol use. +Payload is a Routing message. +ENCODING: Protobuf +""" +ADMIN_APP: PortNum.ValueType # 6 +""" +Admin control packets. +Payload is a AdminMessage message. +ENCODING: Protobuf +""" +TEXT_MESSAGE_COMPRESSED_APP: PortNum.ValueType # 7 +""" +Compressed TEXT_MESSAGE payloads. +ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression +NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed +payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress +any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. +""" +WAYPOINT_APP: PortNum.ValueType # 8 +""" +Waypoint payloads. +Payload is a Waypoint message. +ENCODING: Protobuf +""" +AUDIO_APP: PortNum.ValueType # 9 +""" +Audio Payloads. +Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now +ENCODING: codec2 audio frames +NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. +This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. +""" +DETECTION_SENSOR_APP: PortNum.ValueType # 10 +""" +Same as Text Message but originating from Detection Sensor Module. +NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 +""" +REPLY_APP: PortNum.ValueType # 32 +""" +Provides a 'ping' service that replies to any packet it receives. +Also serves as a small example module. +ENCODING: ASCII Plaintext +""" +IP_TUNNEL_APP: PortNum.ValueType # 33 +""" +Used for the python IP tunnel feature +ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. +""" +PAXCOUNTER_APP: PortNum.ValueType # 34 +""" +Paxcounter lib included in the firmware +ENCODING: protobuf +""" +SERIAL_APP: PortNum.ValueType # 64 +""" +Provides a hardware serial interface to send and receive from the Meshtastic network. +Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic +network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. +Maximum packet size of 240 bytes. +Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. +ENCODING: binary undefined +""" +STORE_FORWARD_APP: PortNum.ValueType # 65 +""" +STORE_FORWARD_APP (Work in Progress) +Maintained by Jm Casler (MC Hamster) : jm@casler.org +ENCODING: Protobuf +""" +RANGE_TEST_APP: PortNum.ValueType # 66 +""" +Optional port for messages for the range test module. +ENCODING: ASCII Plaintext +NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 +""" +TELEMETRY_APP: PortNum.ValueType # 67 +""" +Provides a format to send and receive telemetry data from the Meshtastic network. +Maintained by Charles Crossan (crossan007) : crossan007@gmail.com +ENCODING: Protobuf +""" +ZPS_APP: PortNum.ValueType # 68 +""" +Experimental tools for estimating node position without a GPS +Maintained by Github user a-f-G-U-C (a Meshtastic contributor) +Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS +ENCODING: arrays of int64 fields +""" +SIMULATOR_APP: PortNum.ValueType # 69 +""" +Used to let multiple instances of Linux native applications communicate +as if they did using their LoRa chip. +Maintained by GitHub user GUVWAF. +Project files at https://github.com/GUVWAF/Meshtasticator +ENCODING: Protobuf (?) +""" +TRACEROUTE_APP: PortNum.ValueType # 70 +""" +Provides a traceroute functionality to show the route a packet towards +a certain destination would take on the mesh. +ENCODING: Protobuf +""" +NEIGHBORINFO_APP: PortNum.ValueType # 71 +""" +Aggregates edge info for the network by sending out a list of each node's neighbors +ENCODING: Protobuf +""" +ATAK_PLUGIN: PortNum.ValueType # 72 +""" +ATAK Plugin +Portnum for payloads from the official Meshtastic ATAK plugin +""" +MAP_REPORT_APP: PortNum.ValueType # 73 +""" +Provides unencrypted information about a node for consumption by a map via MQTT +""" +PRIVATE_APP: PortNum.ValueType # 256 +""" +Private applications should use portnums >= 256. +To simplify initial development and testing you can use "PRIVATE_APP" +in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) +""" +ATAK_FORWARDER: PortNum.ValueType # 257 +""" +ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder +ENCODING: libcotshrink +""" +MAX: PortNum.ValueType # 511 +""" +Currently we limit port nums to no higher than this value +""" +global___PortNum = PortNum diff --git a/meshtastic/protobuf/remote_hardware_pb2.py b/meshtastic/protobuf/remote_hardware_pb2.py new file mode 100644 index 0000000..8f43c83 --- /dev/null +++ b/meshtastic/protobuf/remote_hardware_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/remote_hardware.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/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\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 + _globals['_HARDWAREMESSAGE_TYPE']._serialized_end=290 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/remote_hardware_pb2.pyi b/meshtastic/protobuf/remote_hardware_pb2.pyi new file mode 100644 index 0000000..c2f7afa --- /dev/null +++ b/meshtastic/protobuf/remote_hardware_pb2.pyi @@ -0,0 +1,126 @@ +""" +@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 + +@typing.final +class HardwareMessage(google.protobuf.message.Message): + """ + An example app to show off the module system. This message is used for + REMOTE_HARDWARE_APP PortNums. + Also provides easy remote access to any GPIO. + In the future other remote hardware operations can be added based on user interest + (i.e. serial output, spi/i2c input/output). + FIXME - currently this feature is turned on by default which is dangerous + because no security yet (beyond the channel mechanism). + It should be off by default and then protected based on some TBD mechanism + (a special channel once multichannel support is included?) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[HardwareMessage._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: HardwareMessage._Type.ValueType # 0 + """ + Unset/unused + """ + WRITE_GPIOS: HardwareMessage._Type.ValueType # 1 + """ + Set gpio gpios based on gpio_mask/gpio_value + """ + WATCH_GPIOS: HardwareMessage._Type.ValueType # 2 + """ + We are now interested in watching the gpio_mask gpios. + If the selected gpios change, please broadcast GPIOS_CHANGED. + Will implicitly change the gpios requested to be INPUT gpios. + """ + GPIOS_CHANGED: HardwareMessage._Type.ValueType # 3 + """ + The gpios listed in gpio_mask have changed, the new values are listed in gpio_value + """ + READ_GPIOS: HardwareMessage._Type.ValueType # 4 + """ + Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated + """ + READ_GPIOS_REPLY: HardwareMessage._Type.ValueType # 5 + """ + A reply to READ_GPIOS. gpio_mask and gpio_value will be populated + """ + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): + """ + TODO: REPLACE + """ + + UNSET: HardwareMessage.Type.ValueType # 0 + """ + Unset/unused + """ + WRITE_GPIOS: HardwareMessage.Type.ValueType # 1 + """ + Set gpio gpios based on gpio_mask/gpio_value + """ + WATCH_GPIOS: HardwareMessage.Type.ValueType # 2 + """ + We are now interested in watching the gpio_mask gpios. + If the selected gpios change, please broadcast GPIOS_CHANGED. + Will implicitly change the gpios requested to be INPUT gpios. + """ + GPIOS_CHANGED: HardwareMessage.Type.ValueType # 3 + """ + The gpios listed in gpio_mask have changed, the new values are listed in gpio_value + """ + READ_GPIOS: HardwareMessage.Type.ValueType # 4 + """ + Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated + """ + READ_GPIOS_REPLY: HardwareMessage.Type.ValueType # 5 + """ + A reply to READ_GPIOS. gpio_mask and gpio_value will be populated + """ + + TYPE_FIELD_NUMBER: builtins.int + GPIO_MASK_FIELD_NUMBER: builtins.int + GPIO_VALUE_FIELD_NUMBER: builtins.int + type: global___HardwareMessage.Type.ValueType + """ + What type of HardwareMessage is this? + """ + gpio_mask: builtins.int + """ + What gpios are we changing. Not used for all MessageTypes, see MessageType for details + """ + gpio_value: builtins.int + """ + For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios. + Not used for all MessageTypes, see MessageType for details + """ + def __init__( + self, + *, + type: global___HardwareMessage.Type.ValueType = ..., + gpio_mask: builtins.int = ..., + gpio_value: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["gpio_mask", b"gpio_mask", "gpio_value", b"gpio_value", "type", b"type"]) -> None: ... + +global___HardwareMessage = HardwareMessage diff --git a/meshtastic/protobuf/rtttl_pb2.py b/meshtastic/protobuf/rtttl_pb2.py new file mode 100644 index 0000000..07c480d --- /dev/null +++ b/meshtastic/protobuf/rtttl_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/rtttl.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import 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\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\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) diff --git a/meshtastic/protobuf/rtttl_pb2.pyi b/meshtastic/protobuf/rtttl_pb2.pyi new file mode 100644 index 0000000..fe91f94 --- /dev/null +++ b/meshtastic/protobuf/rtttl_pb2.pyi @@ -0,0 +1,33 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class RTTTLConfig(google.protobuf.message.Message): + """ + Canned message module configuration. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RINGTONE_FIELD_NUMBER: builtins.int + ringtone: builtins.str + """ + Ringtone for PWM Buzzer in RTTTL Format. + """ + def __init__( + self, + *, + ringtone: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ringtone", b"ringtone"]) -> None: ... + +global___RTTTLConfig = RTTTLConfig diff --git a/meshtastic/protobuf/storeforward_pb2.py b/meshtastic/protobuf/storeforward_pb2.py new file mode 100644 index 0000000..16a152e --- /dev/null +++ b/meshtastic/protobuf/storeforward_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/storeforward.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/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\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 + _globals['_STOREANDFORWARD_STATISTICS']._serialized_end=571 + _globals['_STOREANDFORWARD_HISTORY']._serialized_start=573 + _globals['_STOREANDFORWARD_HISTORY']._serialized_end=646 + _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_start=648 + _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_end=694 + _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_start=697 + _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_end=1013 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/storeforward_pb2.pyi b/meshtastic/protobuf/storeforward_pb2.pyi new file mode 100644 index 0000000..aff4f74 --- /dev/null +++ b/meshtastic/protobuf/storeforward_pb2.pyi @@ -0,0 +1,345 @@ +""" +@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 + +@typing.final +class StoreAndForward(google.protobuf.message.Message): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _RequestResponse: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RequestResponseEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StoreAndForward._RequestResponse.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: StoreAndForward._RequestResponse.ValueType # 0 + """ + Unset/unused + """ + ROUTER_ERROR: StoreAndForward._RequestResponse.ValueType # 1 + """ + Router is an in error state. + """ + ROUTER_HEARTBEAT: StoreAndForward._RequestResponse.ValueType # 2 + """ + Router heartbeat + """ + ROUTER_PING: StoreAndForward._RequestResponse.ValueType # 3 + """ + Router has requested the client respond. This can work as a + "are you there" message. + """ + ROUTER_PONG: StoreAndForward._RequestResponse.ValueType # 4 + """ + The response to a "Ping" + """ + ROUTER_BUSY: StoreAndForward._RequestResponse.ValueType # 5 + """ + Router is currently busy. Please try again later. + """ + ROUTER_HISTORY: StoreAndForward._RequestResponse.ValueType # 6 + """ + Router is responding to a request for history. + """ + ROUTER_STATS: StoreAndForward._RequestResponse.ValueType # 7 + """ + Router is responding to a request for stats. + """ + ROUTER_TEXT_DIRECT: StoreAndForward._RequestResponse.ValueType # 8 + """ + Router sends a text message from its history that was a direct message. + """ + ROUTER_TEXT_BROADCAST: StoreAndForward._RequestResponse.ValueType # 9 + """ + Router sends a text message from its history that was a broadcast. + """ + CLIENT_ERROR: StoreAndForward._RequestResponse.ValueType # 64 + """ + Client is an in error state. + """ + CLIENT_HISTORY: StoreAndForward._RequestResponse.ValueType # 65 + """ + Client has requested a replay from the router. + """ + CLIENT_STATS: StoreAndForward._RequestResponse.ValueType # 66 + """ + Client has requested stats from the router. + """ + CLIENT_PING: StoreAndForward._RequestResponse.ValueType # 67 + """ + Client has requested the router respond. This can work as a + "are you there" message. + """ + CLIENT_PONG: StoreAndForward._RequestResponse.ValueType # 68 + """ + The response to a "Ping" + """ + CLIENT_ABORT: StoreAndForward._RequestResponse.ValueType # 106 + """ + Client has requested that the router abort processing the client's request + """ + + class RequestResponse(_RequestResponse, metaclass=_RequestResponseEnumTypeWrapper): + """ + 001 - 063 = From Router + 064 - 127 = From Client + """ + + UNSET: StoreAndForward.RequestResponse.ValueType # 0 + """ + Unset/unused + """ + ROUTER_ERROR: StoreAndForward.RequestResponse.ValueType # 1 + """ + Router is an in error state. + """ + ROUTER_HEARTBEAT: StoreAndForward.RequestResponse.ValueType # 2 + """ + Router heartbeat + """ + ROUTER_PING: StoreAndForward.RequestResponse.ValueType # 3 + """ + Router has requested the client respond. This can work as a + "are you there" message. + """ + ROUTER_PONG: StoreAndForward.RequestResponse.ValueType # 4 + """ + The response to a "Ping" + """ + ROUTER_BUSY: StoreAndForward.RequestResponse.ValueType # 5 + """ + Router is currently busy. Please try again later. + """ + ROUTER_HISTORY: StoreAndForward.RequestResponse.ValueType # 6 + """ + Router is responding to a request for history. + """ + ROUTER_STATS: StoreAndForward.RequestResponse.ValueType # 7 + """ + Router is responding to a request for stats. + """ + ROUTER_TEXT_DIRECT: StoreAndForward.RequestResponse.ValueType # 8 + """ + Router sends a text message from its history that was a direct message. + """ + ROUTER_TEXT_BROADCAST: StoreAndForward.RequestResponse.ValueType # 9 + """ + Router sends a text message from its history that was a broadcast. + """ + CLIENT_ERROR: StoreAndForward.RequestResponse.ValueType # 64 + """ + Client is an in error state. + """ + CLIENT_HISTORY: StoreAndForward.RequestResponse.ValueType # 65 + """ + Client has requested a replay from the router. + """ + CLIENT_STATS: StoreAndForward.RequestResponse.ValueType # 66 + """ + Client has requested stats from the router. + """ + CLIENT_PING: StoreAndForward.RequestResponse.ValueType # 67 + """ + Client has requested the router respond. This can work as a + "are you there" message. + """ + CLIENT_PONG: StoreAndForward.RequestResponse.ValueType # 68 + """ + The response to a "Ping" + """ + CLIENT_ABORT: StoreAndForward.RequestResponse.ValueType # 106 + """ + Client has requested that the router abort processing the client's request + """ + + @typing.final + class Statistics(google.protobuf.message.Message): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MESSAGES_TOTAL_FIELD_NUMBER: builtins.int + MESSAGES_SAVED_FIELD_NUMBER: builtins.int + MESSAGES_MAX_FIELD_NUMBER: builtins.int + UP_TIME_FIELD_NUMBER: builtins.int + REQUESTS_FIELD_NUMBER: builtins.int + REQUESTS_HISTORY_FIELD_NUMBER: builtins.int + HEARTBEAT_FIELD_NUMBER: builtins.int + RETURN_MAX_FIELD_NUMBER: builtins.int + RETURN_WINDOW_FIELD_NUMBER: builtins.int + messages_total: builtins.int + """ + Number of messages we have ever seen + """ + messages_saved: builtins.int + """ + Number of messages we have currently saved our history. + """ + messages_max: builtins.int + """ + Maximum number of messages we will save + """ + up_time: builtins.int + """ + Router uptime in seconds + """ + requests: builtins.int + """ + Number of times any client sent a request to the S&F. + """ + requests_history: builtins.int + """ + Number of times the history was requested. + """ + heartbeat: builtins.bool + """ + Is the heartbeat enabled on the server? + """ + return_max: builtins.int + """ + Maximum number of messages the server will return. + """ + return_window: builtins.int + """ + Maximum history window in minutes the server will return messages from. + """ + def __init__( + self, + *, + messages_total: builtins.int = ..., + messages_saved: builtins.int = ..., + messages_max: builtins.int = ..., + up_time: builtins.int = ..., + requests: builtins.int = ..., + requests_history: builtins.int = ..., + heartbeat: builtins.bool = ..., + return_max: builtins.int = ..., + return_window: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "messages_max", b"messages_max", "messages_saved", b"messages_saved", "messages_total", b"messages_total", "requests", b"requests", "requests_history", b"requests_history", "return_max", b"return_max", "return_window", b"return_window", "up_time", b"up_time"]) -> None: ... + + @typing.final + class History(google.protobuf.message.Message): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + HISTORY_MESSAGES_FIELD_NUMBER: builtins.int + WINDOW_FIELD_NUMBER: builtins.int + LAST_REQUEST_FIELD_NUMBER: builtins.int + history_messages: builtins.int + """ + Number of that will be sent to the client + """ + window: builtins.int + """ + The window of messages that was used to filter the history client requested + """ + last_request: builtins.int + """ + Index in the packet history of the last message sent in a previous request to the server. + Will be sent to the client before sending the history and can be set in a subsequent request to avoid getting packets the server already sent to the client. + """ + def __init__( + self, + *, + history_messages: builtins.int = ..., + window: builtins.int = ..., + last_request: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["history_messages", b"history_messages", "last_request", b"last_request", "window", b"window"]) -> None: ... + + @typing.final + class Heartbeat(google.protobuf.message.Message): + """ + TODO: REPLACE + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PERIOD_FIELD_NUMBER: builtins.int + SECONDARY_FIELD_NUMBER: builtins.int + period: builtins.int + """ + Period in seconds that the heartbeat is sent out that will be sent to the client + """ + secondary: builtins.int + """ + If set, this is not the primary Store & Forward router on the mesh + """ + def __init__( + self, + *, + period: builtins.int = ..., + secondary: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["period", b"period", "secondary", b"secondary"]) -> None: ... + + RR_FIELD_NUMBER: builtins.int + STATS_FIELD_NUMBER: builtins.int + HISTORY_FIELD_NUMBER: builtins.int + HEARTBEAT_FIELD_NUMBER: builtins.int + TEXT_FIELD_NUMBER: builtins.int + rr: global___StoreAndForward.RequestResponse.ValueType + """ + TODO: REPLACE + """ + text: builtins.bytes + """ + Text from history message. + """ + @property + def stats(self) -> global___StoreAndForward.Statistics: + """ + TODO: REPLACE + """ + + @property + def history(self) -> global___StoreAndForward.History: + """ + TODO: REPLACE + """ + + @property + def heartbeat(self) -> global___StoreAndForward.Heartbeat: + """ + TODO: REPLACE + """ + + def __init__( + self, + *, + rr: global___StoreAndForward.RequestResponse.ValueType = ..., + stats: global___StoreAndForward.Statistics | None = ..., + history: global___StoreAndForward.History | None = ..., + heartbeat: global___StoreAndForward.Heartbeat | None = ..., + text: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "history", b"history", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "history", b"history", "rr", b"rr", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["stats", "history", "heartbeat", "text"] | None: ... + +global___StoreAndForward = StoreAndForward diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py new file mode 100644 index 0000000..9c2cf4e --- /dev/null +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/telemetry.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/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xa6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant*\xdd\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"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.telemetry_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _globals['_TELEMETRYSENSORTYPE']._serialized_start=1259 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=1608 + _globals['_DEVICEMETRICS']._serialized_start=61 + _globals['_DEVICEMETRICS']._serialized_end=190 + _globals['_ENVIRONMENTMETRICS']._serialized_start=193 + _globals['_ENVIRONMENTMETRICS']._serialized_end=487 + _globals['_POWERMETRICS']._serialized_start=490 + _globals['_POWERMETRICS']._serialized_end=630 + _globals['_AIRQUALITYMETRICS']._serialized_start=633 + _globals['_AIRQUALITYMETRICS']._serialized_end=952 + _globals['_TELEMETRY']._serialized_start=955 + _globals['_TELEMETRY']._serialized_end=1256 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi new file mode 100644 index 0000000..aba51c8 --- /dev/null +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -0,0 +1,576 @@ +""" +@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 _TelemetrySensorType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TelemetrySensorType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SENSOR_UNSET: _TelemetrySensorType.ValueType # 0 + """ + No external telemetry sensor explicitly set + """ + BME280: _TelemetrySensorType.ValueType # 1 + """ + High accuracy temperature, pressure, humidity + """ + BME680: _TelemetrySensorType.ValueType # 2 + """ + High accuracy temperature, pressure, humidity, and air resistance + """ + MCP9808: _TelemetrySensorType.ValueType # 3 + """ + Very high accuracy temperature + """ + INA260: _TelemetrySensorType.ValueType # 4 + """ + Moderate accuracy current and voltage + """ + INA219: _TelemetrySensorType.ValueType # 5 + """ + Moderate accuracy current and voltage + """ + BMP280: _TelemetrySensorType.ValueType # 6 + """ + High accuracy temperature and pressure + """ + SHTC3: _TelemetrySensorType.ValueType # 7 + """ + High accuracy temperature and humidity + """ + LPS22: _TelemetrySensorType.ValueType # 8 + """ + High accuracy pressure + """ + QMC6310: _TelemetrySensorType.ValueType # 9 + """ + 3-Axis magnetic sensor + """ + QMI8658: _TelemetrySensorType.ValueType # 10 + """ + 6-Axis inertial measurement sensor + """ + QMC5883L: _TelemetrySensorType.ValueType # 11 + """ + 3-Axis magnetic sensor + """ + SHT31: _TelemetrySensorType.ValueType # 12 + """ + High accuracy temperature and humidity + """ + PMSA003I: _TelemetrySensorType.ValueType # 13 + """ + PM2.5 air quality sensor + """ + INA3221: _TelemetrySensorType.ValueType # 14 + """ + INA3221 3 Channel Voltage / Current Sensor + """ + BMP085: _TelemetrySensorType.ValueType # 15 + """ + BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) + """ + RCWL9620: _TelemetrySensorType.ValueType # 16 + """ + RCWL-9620 Doppler Radar Distance Sensor, used for water level detection + """ + SHT4X: _TelemetrySensorType.ValueType # 17 + """ + Sensirion High accuracy temperature and humidity + """ + VEML7700: _TelemetrySensorType.ValueType # 18 + """ + VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. + """ + MLX90632: _TelemetrySensorType.ValueType # 19 + """ + MLX90632 non-contact IR temperature sensor. + """ + OPT3001: _TelemetrySensorType.ValueType # 20 + """ + TI OPT3001 Ambient Light Sensor + """ + LTR390UV: _TelemetrySensorType.ValueType # 21 + """ + Lite On LTR-390UV-01 UV Light Sensor + """ + TSL25911FN: _TelemetrySensorType.ValueType # 22 + """ + AMS TSL25911FN RGB Light Sensor + """ + AHT10: _TelemetrySensorType.ValueType # 23 + """ + AHT10 Integrated temperature and humidity sensor + """ + DFROBOT_LARK: _TelemetrySensorType.ValueType # 24 + """ + DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) + """ + +class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): + """ + Supported I2C Sensors for telemetry in Meshtastic + """ + +SENSOR_UNSET: TelemetrySensorType.ValueType # 0 +""" +No external telemetry sensor explicitly set +""" +BME280: TelemetrySensorType.ValueType # 1 +""" +High accuracy temperature, pressure, humidity +""" +BME680: TelemetrySensorType.ValueType # 2 +""" +High accuracy temperature, pressure, humidity, and air resistance +""" +MCP9808: TelemetrySensorType.ValueType # 3 +""" +Very high accuracy temperature +""" +INA260: TelemetrySensorType.ValueType # 4 +""" +Moderate accuracy current and voltage +""" +INA219: TelemetrySensorType.ValueType # 5 +""" +Moderate accuracy current and voltage +""" +BMP280: TelemetrySensorType.ValueType # 6 +""" +High accuracy temperature and pressure +""" +SHTC3: TelemetrySensorType.ValueType # 7 +""" +High accuracy temperature and humidity +""" +LPS22: TelemetrySensorType.ValueType # 8 +""" +High accuracy pressure +""" +QMC6310: TelemetrySensorType.ValueType # 9 +""" +3-Axis magnetic sensor +""" +QMI8658: TelemetrySensorType.ValueType # 10 +""" +6-Axis inertial measurement sensor +""" +QMC5883L: TelemetrySensorType.ValueType # 11 +""" +3-Axis magnetic sensor +""" +SHT31: TelemetrySensorType.ValueType # 12 +""" +High accuracy temperature and humidity +""" +PMSA003I: TelemetrySensorType.ValueType # 13 +""" +PM2.5 air quality sensor +""" +INA3221: TelemetrySensorType.ValueType # 14 +""" +INA3221 3 Channel Voltage / Current Sensor +""" +BMP085: TelemetrySensorType.ValueType # 15 +""" +BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) +""" +RCWL9620: TelemetrySensorType.ValueType # 16 +""" +RCWL-9620 Doppler Radar Distance Sensor, used for water level detection +""" +SHT4X: TelemetrySensorType.ValueType # 17 +""" +Sensirion High accuracy temperature and humidity +""" +VEML7700: TelemetrySensorType.ValueType # 18 +""" +VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. +""" +MLX90632: TelemetrySensorType.ValueType # 19 +""" +MLX90632 non-contact IR temperature sensor. +""" +OPT3001: TelemetrySensorType.ValueType # 20 +""" +TI OPT3001 Ambient Light Sensor +""" +LTR390UV: TelemetrySensorType.ValueType # 21 +""" +Lite On LTR-390UV-01 UV Light Sensor +""" +TSL25911FN: TelemetrySensorType.ValueType # 22 +""" +AMS TSL25911FN RGB Light Sensor +""" +AHT10: TelemetrySensorType.ValueType # 23 +""" +AHT10 Integrated temperature and humidity sensor +""" +DFROBOT_LARK: TelemetrySensorType.ValueType # 24 +""" +DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) +""" +global___TelemetrySensorType = TelemetrySensorType + +@typing.final +class DeviceMetrics(google.protobuf.message.Message): + """ + Key native device metrics such as battery level + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BATTERY_LEVEL_FIELD_NUMBER: builtins.int + VOLTAGE_FIELD_NUMBER: builtins.int + CHANNEL_UTILIZATION_FIELD_NUMBER: builtins.int + AIR_UTIL_TX_FIELD_NUMBER: builtins.int + UPTIME_SECONDS_FIELD_NUMBER: builtins.int + battery_level: builtins.int + """ + 0-100 (>100 means powered) + """ + voltage: builtins.float + """ + Voltage measured + """ + channel_utilization: builtins.float + """ + Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). + """ + air_util_tx: builtins.float + """ + Percent of airtime for transmission used within the last hour. + """ + uptime_seconds: builtins.int + """ + How long the device has been running since the last reboot (in seconds) + """ + def __init__( + self, + *, + battery_level: builtins.int = ..., + voltage: builtins.float = ..., + channel_utilization: builtins.float = ..., + air_util_tx: builtins.float = ..., + uptime_seconds: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["air_util_tx", b"air_util_tx", "battery_level", b"battery_level", "channel_utilization", b"channel_utilization", "uptime_seconds", b"uptime_seconds", "voltage", b"voltage"]) -> None: ... + +global___DeviceMetrics = DeviceMetrics + +@typing.final +class EnvironmentMetrics(google.protobuf.message.Message): + """ + Weather station or other environmental metrics + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TEMPERATURE_FIELD_NUMBER: builtins.int + RELATIVE_HUMIDITY_FIELD_NUMBER: builtins.int + BAROMETRIC_PRESSURE_FIELD_NUMBER: builtins.int + GAS_RESISTANCE_FIELD_NUMBER: builtins.int + VOLTAGE_FIELD_NUMBER: builtins.int + CURRENT_FIELD_NUMBER: builtins.int + IAQ_FIELD_NUMBER: builtins.int + DISTANCE_FIELD_NUMBER: builtins.int + LUX_FIELD_NUMBER: builtins.int + WHITE_LUX_FIELD_NUMBER: builtins.int + IR_LUX_FIELD_NUMBER: builtins.int + UV_LUX_FIELD_NUMBER: builtins.int + WIND_DIRECTION_FIELD_NUMBER: builtins.int + WIND_SPEED_FIELD_NUMBER: builtins.int + temperature: builtins.float + """ + Temperature measured + """ + relative_humidity: builtins.float + """ + Relative humidity percent measured + """ + barometric_pressure: builtins.float + """ + Barometric pressure in hPA measured + """ + gas_resistance: builtins.float + """ + Gas resistance in MOhm measured + """ + voltage: builtins.float + """ + Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) + """ + current: builtins.float + """ + Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) + """ + iaq: builtins.int + """ + relative scale IAQ value as measured by Bosch BME680 . value 0-500. + Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. + """ + distance: builtins.float + """ + RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm. + """ + lux: builtins.float + """ + VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. + """ + white_lux: builtins.float + """ + VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor. + """ + ir_lux: builtins.float + """ + Infrared lux + """ + uv_lux: builtins.float + """ + Ultraviolet lux + """ + wind_direction: builtins.int + """ + Wind direction in degrees + 0 degrees = North, 90 = East, etc... + """ + wind_speed: builtins.float + """ + Wind speed in m/s + """ + def __init__( + self, + *, + temperature: builtins.float = ..., + relative_humidity: builtins.float = ..., + barometric_pressure: builtins.float = ..., + gas_resistance: builtins.float = ..., + voltage: builtins.float = ..., + current: builtins.float = ..., + iaq: builtins.int = ..., + distance: builtins.float = ..., + lux: builtins.float = ..., + white_lux: builtins.float = ..., + ir_lux: builtins.float = ..., + uv_lux: builtins.float = ..., + wind_direction: builtins.int = ..., + wind_speed: builtins.float = ..., + ) -> None: ... + 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", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_speed", b"wind_speed"]) -> None: ... + +global___EnvironmentMetrics = EnvironmentMetrics + +@typing.final +class PowerMetrics(google.protobuf.message.Message): + """ + Power Metrics (voltage / current / etc) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CH1_VOLTAGE_FIELD_NUMBER: builtins.int + CH1_CURRENT_FIELD_NUMBER: builtins.int + CH2_VOLTAGE_FIELD_NUMBER: builtins.int + CH2_CURRENT_FIELD_NUMBER: builtins.int + CH3_VOLTAGE_FIELD_NUMBER: builtins.int + CH3_CURRENT_FIELD_NUMBER: builtins.int + ch1_voltage: builtins.float + """ + Voltage (Ch1) + """ + ch1_current: builtins.float + """ + Current (Ch1) + """ + ch2_voltage: builtins.float + """ + Voltage (Ch2) + """ + ch2_current: builtins.float + """ + Current (Ch2) + """ + ch3_voltage: builtins.float + """ + Voltage (Ch3) + """ + ch3_current: builtins.float + """ + Current (Ch3) + """ + def __init__( + self, + *, + ch1_voltage: builtins.float = ..., + ch1_current: builtins.float = ..., + ch2_voltage: builtins.float = ..., + ch2_current: builtins.float = ..., + ch3_voltage: builtins.float = ..., + ch3_current: builtins.float = ..., + ) -> None: ... + 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"]) -> None: ... + +global___PowerMetrics = PowerMetrics + +@typing.final +class AirQualityMetrics(google.protobuf.message.Message): + """ + Air quality metrics + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PM10_STANDARD_FIELD_NUMBER: builtins.int + PM25_STANDARD_FIELD_NUMBER: builtins.int + PM100_STANDARD_FIELD_NUMBER: builtins.int + PM10_ENVIRONMENTAL_FIELD_NUMBER: builtins.int + PM25_ENVIRONMENTAL_FIELD_NUMBER: builtins.int + PM100_ENVIRONMENTAL_FIELD_NUMBER: builtins.int + PARTICLES_03UM_FIELD_NUMBER: builtins.int + PARTICLES_05UM_FIELD_NUMBER: builtins.int + PARTICLES_10UM_FIELD_NUMBER: builtins.int + PARTICLES_25UM_FIELD_NUMBER: builtins.int + PARTICLES_50UM_FIELD_NUMBER: builtins.int + PARTICLES_100UM_FIELD_NUMBER: builtins.int + pm10_standard: builtins.int + """ + Concentration Units Standard PM1.0 + """ + pm25_standard: builtins.int + """ + Concentration Units Standard PM2.5 + """ + pm100_standard: builtins.int + """ + Concentration Units Standard PM10.0 + """ + pm10_environmental: builtins.int + """ + Concentration Units Environmental PM1.0 + """ + pm25_environmental: builtins.int + """ + Concentration Units Environmental PM2.5 + """ + pm100_environmental: builtins.int + """ + Concentration Units Environmental PM10.0 + """ + particles_03um: builtins.int + """ + 0.3um Particle Count + """ + particles_05um: builtins.int + """ + 0.5um Particle Count + """ + particles_10um: builtins.int + """ + 1.0um Particle Count + """ + particles_25um: builtins.int + """ + 2.5um Particle Count + """ + particles_50um: builtins.int + """ + 5.0um Particle Count + """ + particles_100um: builtins.int + """ + 10.0um Particle Count + """ + def __init__( + self, + *, + pm10_standard: builtins.int = ..., + pm25_standard: builtins.int = ..., + pm100_standard: builtins.int = ..., + pm10_environmental: builtins.int = ..., + pm25_environmental: builtins.int = ..., + pm100_environmental: builtins.int = ..., + particles_03um: builtins.int = ..., + particles_05um: builtins.int = ..., + particles_10um: builtins.int = ..., + particles_25um: builtins.int = ..., + particles_50um: builtins.int = ..., + particles_100um: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["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: ... + +global___AirQualityMetrics = AirQualityMetrics + +@typing.final +class Telemetry(google.protobuf.message.Message): + """ + Types of Measurements the telemetry module is equipped to handle + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_FIELD_NUMBER: builtins.int + DEVICE_METRICS_FIELD_NUMBER: builtins.int + ENVIRONMENT_METRICS_FIELD_NUMBER: builtins.int + AIR_QUALITY_METRICS_FIELD_NUMBER: builtins.int + POWER_METRICS_FIELD_NUMBER: builtins.int + time: builtins.int + """ + Seconds since 1970 - or 0 for unknown/unset + """ + @property + def device_metrics(self) -> global___DeviceMetrics: + """ + Key native device metrics such as battery level + """ + + @property + def environment_metrics(self) -> global___EnvironmentMetrics: + """ + Weather station or other environmental metrics + """ + + @property + def air_quality_metrics(self) -> global___AirQualityMetrics: + """ + Air quality metrics + """ + + @property + def power_metrics(self) -> global___PowerMetrics: + """ + Power Metrics + """ + + def __init__( + self, + *, + time: builtins.int = ..., + device_metrics: global___DeviceMetrics | None = ..., + environment_metrics: global___EnvironmentMetrics | None = ..., + air_quality_metrics: global___AirQualityMetrics | None = ..., + power_metrics: global___PowerMetrics | 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", "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", "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"] | None: ... + +global___Telemetry = Telemetry diff --git a/meshtastic/protobuf/xmodem_pb2.py b/meshtastic/protobuf/xmodem_pb2.py new file mode 100644 index 0000000..fc179f6 --- /dev/null +++ b/meshtastic/protobuf/xmodem_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/xmodem.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import 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/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\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 + _globals['_XMODEM_CONTROL']._serialized_end=249 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/xmodem_pb2.pyi b/meshtastic/protobuf/xmodem_pb2.pyi new file mode 100644 index 0000000..d362ad0 --- /dev/null +++ b/meshtastic/protobuf/xmodem_pb2.pyi @@ -0,0 +1,67 @@ +""" +@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 + +@typing.final +class XModem(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Control: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ControlEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[XModem._Control.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NUL: XModem._Control.ValueType # 0 + SOH: XModem._Control.ValueType # 1 + STX: XModem._Control.ValueType # 2 + EOT: XModem._Control.ValueType # 4 + ACK: XModem._Control.ValueType # 6 + NAK: XModem._Control.ValueType # 21 + CAN: XModem._Control.ValueType # 24 + CTRLZ: XModem._Control.ValueType # 26 + + class Control(_Control, metaclass=_ControlEnumTypeWrapper): ... + NUL: XModem.Control.ValueType # 0 + SOH: XModem.Control.ValueType # 1 + STX: XModem.Control.ValueType # 2 + EOT: XModem.Control.ValueType # 4 + ACK: XModem.Control.ValueType # 6 + NAK: XModem.Control.ValueType # 21 + CAN: XModem.Control.ValueType # 24 + CTRLZ: XModem.Control.ValueType # 26 + + CONTROL_FIELD_NUMBER: builtins.int + SEQ_FIELD_NUMBER: builtins.int + CRC16_FIELD_NUMBER: builtins.int + BUFFER_FIELD_NUMBER: builtins.int + control: global___XModem.Control.ValueType + seq: builtins.int + crc16: builtins.int + buffer: builtins.bytes + def __init__( + self, + *, + control: global___XModem.Control.ValueType = ..., + seq: builtins.int = ..., + crc16: builtins.int = ..., + buffer: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["buffer", b"buffer", "control", b"control", "crc16", b"crc16", "seq", b"seq"]) -> None: ... + +global___XModem = XModem From 3e8a807868a12694aa29fa5103952f50b7f40747 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 10:17:37 -0700 Subject: [PATCH 068/248] Update all libs to latest (in particular the mypy-protobuf tool) --- poetry.lock | 115 ++++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/poetry.lock b/poetry.lock index dd7228f..29e130e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -57,13 +57,13 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "autopep8" -version = "2.3.0" +version = "2.3.1" description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" optional = false python-versions = ">=3.8" files = [ - {file = "autopep8-2.3.0-py2.py3-none-any.whl", hash = "sha256:b716efa70cbafbf4a2c9c5ec1cabfa037a68f9e30b04c74ffa5864dd49b8f7d2"}, - {file = "autopep8-2.3.0.tar.gz", hash = "sha256:5cfe45eb3bef8662f6a3c7e28b7c0310c7310d340074b7f0f28f9810b44b7ef4"}, + {file = "autopep8-2.3.1-py2.py3-none-any.whl", hash = "sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d"}, + {file = "autopep8-2.3.1.tar.gz", hash = "sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda"}, ] [package.dependencies] @@ -390,13 +390,13 @@ test = ["pytest (>=6)"] [[package]] name = "hypothesis" -version = "6.103.2" +version = "6.104.1" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.103.2-py3-none-any.whl", hash = "sha256:629b7cdeca8c225933739f99879caba21949000d2c919c8b4585e01048b3bc73"}, - {file = "hypothesis-6.103.2.tar.gz", hash = "sha256:83504e31e90a0d7d6e8eb93e51525dc1a48d79c932a50ad6035e29f8295328cd"}, + {file = "hypothesis-6.104.1-py3-none-any.whl", hash = "sha256:a0a898fa78ecaefe76ad248901dc274e598f29198c6015b3053f7f7827670e0e"}, + {file = "hypothesis-6.104.1.tar.gz", hash = "sha256:4033898019a6149823d2feeb8d214921b4ac2d342a05d6b02e40a3ca4be07eea"}, ] [package.dependencies] @@ -405,10 +405,10 @@ exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.54)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.55)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] -crosshair = ["crosshair-tool (>=0.0.54)", "hypothesis-crosshair (>=0.0.4)"] +crosshair = ["crosshair-tool (>=0.0.55)", "hypothesis-crosshair (>=0.0.4)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] @@ -434,13 +434,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.0" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, - {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] @@ -609,38 +609,38 @@ files = [ [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] @@ -764,22 +764,22 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "5.27.1" +version = "5.27.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.27.1-cp310-abi3-win32.whl", hash = "sha256:3adc15ec0ff35c5b2d0992f9345b04a540c1e73bfee3ff1643db43cc1d734333"}, - {file = "protobuf-5.27.1-cp310-abi3-win_amd64.whl", hash = "sha256:25236b69ab4ce1bec413fd4b68a15ef8141794427e0b4dc173e9d5d9dffc3bcd"}, - {file = "protobuf-5.27.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e38fc29d7df32e01a41cf118b5a968b1efd46b9c41ff515234e794011c78b17"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:917ed03c3eb8a2d51c3496359f5b53b4e4b7e40edfbdd3d3f34336e0eef6825a"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:ee52874a9e69a30271649be88ecbe69d374232e8fd0b4e4b0aaaa87f429f1631"}, - {file = "protobuf-5.27.1-cp38-cp38-win32.whl", hash = "sha256:7a97b9c5aed86b9ca289eb5148df6c208ab5bb6906930590961e08f097258107"}, - {file = "protobuf-5.27.1-cp38-cp38-win_amd64.whl", hash = "sha256:f6abd0f69968792da7460d3c2cfa7d94fd74e1c21df321eb6345b963f9ec3d8d"}, - {file = "protobuf-5.27.1-cp39-cp39-win32.whl", hash = "sha256:dfddb7537f789002cc4eb00752c92e67885badcc7005566f2c5de9d969d3282d"}, - {file = "protobuf-5.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:39309898b912ca6febb0084ea912e976482834f401be35840a008da12d189340"}, - {file = "protobuf-5.27.1-py3-none-any.whl", hash = "sha256:4ac7249a1530a2ed50e24201d6630125ced04b30619262f06224616e0030b6cf"}, - {file = "protobuf-5.27.1.tar.gz", hash = "sha256:df5e5b8e39b7d1c25b186ffdf9f44f40f810bbcc9d2b71d9d3156fee5a9adf15"}, + {file = "protobuf-5.27.2-cp310-abi3-win32.whl", hash = "sha256:354d84fac2b0d76062e9b3221f4abbbacdfd2a4d8af36bab0474f3a0bb30ab38"}, + {file = "protobuf-5.27.2-cp310-abi3-win_amd64.whl", hash = "sha256:0e341109c609749d501986b835f667c6e1e24531096cff9d34ae411595e26505"}, + {file = "protobuf-5.27.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a109916aaac42bff84702fb5187f3edadbc7c97fc2c99c5ff81dd15dcce0d1e5"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:176c12b1f1c880bf7a76d9f7c75822b6a2bc3db2d28baa4d300e8ce4cde7409b"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b848dbe1d57ed7c191dfc4ea64b8b004a3f9ece4bf4d0d80a367b76df20bf36e"}, + {file = "protobuf-5.27.2-cp38-cp38-win32.whl", hash = "sha256:4fadd8d83e1992eed0248bc50a4a6361dc31bcccc84388c54c86e530b7f58863"}, + {file = "protobuf-5.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:610e700f02469c4a997e58e328cac6f305f649826853813177e6290416e846c6"}, + {file = "protobuf-5.27.2-cp39-cp39-win32.whl", hash = "sha256:9e8f199bf7f97bd7ecebffcae45ebf9527603549b2b562df0fbc6d4d688f14ca"}, + {file = "protobuf-5.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:7fc3add9e6003e026da5fc9e59b131b8f22b428b991ccd53e2af8071687b4fce"}, + {file = "protobuf-5.27.2-py3-none-any.whl", hash = "sha256:54330f07e4949d09614707c48b06d1a22f8ffb5763c159efd5c0928326a91470"}, + {file = "protobuf-5.27.2.tar.gz", hash = "sha256:f3ecdef226b9af856075f28227ff2c90ce3a594d092c39bee5513573f25e2714"}, ] [[package]] @@ -1098,7 +1098,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1156,13 +1155,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "setuptools" -version = "70.1.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, - {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] @@ -1218,13 +1217,13 @@ files = [ [[package]] name = "types-protobuf" -version = "5.26.0.20240422" +version = "5.27.0.20240626" description = "Typing stubs for protobuf" optional = false python-versions = ">=3.8" files = [ - {file = "types-protobuf-5.26.0.20240422.tar.gz", hash = "sha256:e6074178109f97efe9f0b20a035ba61d7c3b03e867eb47d254d2b2ab6a805e36"}, - {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, + {file = "types-protobuf-5.27.0.20240626.tar.gz", hash = "sha256:683ba14043bade6785e3f937a7498f243b37881a91ac8d81b9202ecf8b191e9c"}, + {file = "types_protobuf-5.27.0.20240626-py3-none-any.whl", hash = "sha256:688e8f7e8d9295db26bc560df01fb731b27a25b77cbe4c1ce945647f7024f5c1"}, ] [[package]] From f2c427430c22bffacb8cc4ce381526d606b8872f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 10:21:47 -0700 Subject: [PATCH 069/248] Update protobufs to master (required for powermon stuff) --- meshtastic/protobuf/admin_pb2.py | 20 +++--- meshtastic/protobuf/admin_pb2.pyi | 12 +++- meshtastic/protobuf/config_pb2.py | 60 ++++++++-------- meshtastic/protobuf/config_pb2.pyi | 98 ++++++++++++++++++++++++++- meshtastic/protobuf/mesh_pb2.py | 58 ++++++++-------- meshtastic/protobuf/mesh_pb2.pyi | 66 +++++++++++++++++- meshtastic/protobuf/powermon_pb2.py | 28 ++++++++ meshtastic/protobuf/powermon_pb2.pyi | 97 ++++++++++++++++++++++++++ meshtastic/protobuf/telemetry_pb2.py | 22 +++--- meshtastic/protobuf/telemetry_pb2.pyi | 44 +++++++++++- protobufs | 2 +- 11 files changed, 419 insertions(+), 88 deletions(-) create mode 100644 meshtastic/protobuf/powermon_pb2.py create mode 100644 meshtastic/protobuf/powermon_pb2.pyi diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index 1429f1e..c002b8f 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -18,7 +18,7 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xd5\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xea\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,13 +27,13 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_ADMINMESSAGE']._serialized_start=244 - _globals['_ADMINMESSAGE']._serialized_end=2633 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2147 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2296 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2299 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2614 - _globals['_HAMPARAMETERS']._serialized_start=2635 - _globals['_HAMPARAMETERS']._serialized_end=2726 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2728 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2839 + _globals['_ADMINMESSAGE']._serialized_end=2654 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2168 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2317 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2320 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2635 + _globals['_HAMPARAMETERS']._serialized_start=2656 + _globals['_HAMPARAMETERS']._serialized_end=2747 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2749 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2860 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index cdfc6b7..0840385 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -241,6 +241,7 @@ class AdminMessage(google.protobuf.message.Message): GET_NODE_REMOTE_HARDWARE_PINS_RESPONSE_FIELD_NUMBER: builtins.int ENTER_DFU_MODE_REQUEST_FIELD_NUMBER: builtins.int DELETE_FILE_REQUEST_FIELD_NUMBER: builtins.int + SET_SCALE_FIELD_NUMBER: builtins.int SET_OWNER_FIELD_NUMBER: builtins.int SET_CHANNEL_FIELD_NUMBER: builtins.int SET_CONFIG_FIELD_NUMBER: builtins.int @@ -314,6 +315,10 @@ class AdminMessage(google.protobuf.message.Message): """ Delete the file by the specified path from the device """ + set_scale: builtins.int + """ + Set zero and offset for scale chips + """ set_canned_message_module_messages: builtins.str """ Set the Canned Message Module messages text. @@ -479,6 +484,7 @@ class AdminMessage(google.protobuf.message.Message): get_node_remote_hardware_pins_response: global___NodeRemoteHardwarePinsResponse | None = ..., enter_dfu_mode_request: builtins.bool = ..., delete_file_request: builtins.str = ..., + set_scale: builtins.int = ..., set_owner: meshtastic.protobuf.mesh_pb2.User | None = ..., set_channel: meshtastic.protobuf.channel_pb2.Channel | None = ..., set_config: meshtastic.protobuf.config_pb2.Config | None = ..., @@ -499,9 +505,9 @@ class AdminMessage(google.protobuf.message.Message): factory_reset: builtins.int = ..., nodedb_reset: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> 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_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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... + def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> 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", "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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... global___AdminMessage = AdminMessage diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index c385527..7aa80b9 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xed \n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xe2\x05\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xbf#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xd6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\x1e\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,7 +26,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=4263 + _globals['_CONFIG']._serialized_end=4601 _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 _globals['_CONFIG_DEVICECONFIG']._serialized_end=1172 _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 @@ -40,31 +40,33 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1788 _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1841 _globals['_CONFIG_POWERCONFIG']._serialized_start=1844 - _globals['_CONFIG_POWERCONFIG']._serialized_end=2078 - _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2081 - _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2481 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2374 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2444 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2446 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2481 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2484 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3222 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=2957 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3034 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3036 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3076 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3078 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3155 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3157 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3222 - _globals['_CONFIG_LORACONFIG']._serialized_start=3225 - _globals['_CONFIG_LORACONFIG']._serialized_end=4059 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=3703 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=3908 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=3911 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4059 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4062 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4244 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4188 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4244 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2104 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2107 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2507 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2400 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2470 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2472 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2507 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2510 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3528 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3074 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3151 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3153 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3193 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3195 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3272 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3274 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3339 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3342 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3528 + _globals['_CONFIG_LORACONFIG']._serialized_start=3531 + _globals['_CONFIG_LORACONFIG']._serialized_end=4365 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4009 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4214 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4217 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4365 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4368 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4582 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4526 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4582 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 49d64de..9da9dc4 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -580,6 +580,7 @@ class Config(google.protobuf.message.Message): LS_SECS_FIELD_NUMBER: builtins.int MIN_WAKE_SECS_FIELD_NUMBER: builtins.int DEVICE_BATTERY_INA_ADDRESS_FIELD_NUMBER: builtins.int + 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. @@ -623,6 +624,11 @@ class Config(google.protobuf.message.Message): """ I2C address of INA_2XX to use for reading device battery voltage """ + powermon_enables: builtins.int + """ + If non-zero, we want powermon log outputs. With the particular (bitfield) sources enabled. + Note: we picked an ID of 32 so that lower more efficient IDs can be used for more frequently used options. + """ def __init__( self, *, @@ -634,8 +640,9 @@ class Config(google.protobuf.message.Message): ls_secs: builtins.int = ..., min_wake_secs: builtins.int = ..., device_battery_ina_address: builtins.int = ..., + powermon_enables: builtins.int = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... + def ClearField(self, field_name: typing.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "powermon_enables", b"powermon_enables", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... @typing.final class NetworkConfig(google.protobuf.message.Message): @@ -960,6 +967,79 @@ class Config(google.protobuf.message.Message): TFT Full Color Displays (not implemented yet) """ + class _CompassOrientation: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _CompassOrientationEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._CompassOrientation.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DEGREES_0: Config.DisplayConfig._CompassOrientation.ValueType # 0 + """ + The compass and the display are in the same orientation. + """ + DEGREES_90: Config.DisplayConfig._CompassOrientation.ValueType # 1 + """ + Rotate the compass by 90 degrees. + """ + DEGREES_180: Config.DisplayConfig._CompassOrientation.ValueType # 2 + """ + Rotate the compass by 180 degrees. + """ + DEGREES_270: Config.DisplayConfig._CompassOrientation.ValueType # 3 + """ + Rotate the compass by 270 degrees. + """ + DEGREES_0_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 4 + """ + Don't rotate the compass, but invert the result. + """ + DEGREES_90_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 5 + """ + Rotate the compass by 90 degrees and invert. + """ + DEGREES_180_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 6 + """ + Rotate the compass by 180 degrees and invert. + """ + DEGREES_270_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 7 + """ + Rotate the compass by 270 degrees and invert. + """ + + class CompassOrientation(_CompassOrientation, metaclass=_CompassOrientationEnumTypeWrapper): ... + DEGREES_0: Config.DisplayConfig.CompassOrientation.ValueType # 0 + """ + The compass and the display are in the same orientation. + """ + DEGREES_90: Config.DisplayConfig.CompassOrientation.ValueType # 1 + """ + Rotate the compass by 90 degrees. + """ + DEGREES_180: Config.DisplayConfig.CompassOrientation.ValueType # 2 + """ + Rotate the compass by 180 degrees. + """ + DEGREES_270: Config.DisplayConfig.CompassOrientation.ValueType # 3 + """ + Rotate the compass by 270 degrees. + """ + DEGREES_0_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 4 + """ + Don't rotate the compass, but invert the result. + """ + DEGREES_90_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 5 + """ + Rotate the compass by 90 degrees and invert. + """ + DEGREES_180_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 6 + """ + Rotate the compass by 180 degrees and invert. + """ + DEGREES_270_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 7 + """ + Rotate the compass by 270 degrees and invert. + """ + SCREEN_ON_SECS_FIELD_NUMBER: builtins.int GPS_FORMAT_FIELD_NUMBER: builtins.int AUTO_SCREEN_CAROUSEL_SECS_FIELD_NUMBER: builtins.int @@ -970,6 +1050,7 @@ class Config(google.protobuf.message.Message): DISPLAYMODE_FIELD_NUMBER: builtins.int HEADING_BOLD_FIELD_NUMBER: builtins.int WAKE_ON_TAP_OR_MOTION_FIELD_NUMBER: builtins.int + COMPASS_ORIENTATION_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 @@ -1013,6 +1094,10 @@ class Config(google.protobuf.message.Message): """ Should we wake the screen up on accelerometer detected motion or tap """ + compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType + """ + Indicates how to rotate or invert the compass output to accurate display on the display. + """ def __init__( self, *, @@ -1026,8 +1111,9 @@ class Config(google.protobuf.message.Message): displaymode: global___Config.DisplayConfig.DisplayMode.ValueType = ..., heading_bold: builtins.bool = ..., wake_on_tap_or_motion: builtins.bool = ..., + compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "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", "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", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... @typing.final class LoRaConfig(google.protobuf.message.Message): @@ -1451,6 +1537,7 @@ class Config(google.protobuf.message.Message): ENABLED_FIELD_NUMBER: builtins.int MODE_FIELD_NUMBER: builtins.int FIXED_PIN_FIELD_NUMBER: builtins.int + DEVICE_LOGGING_ENABLED_FIELD_NUMBER: builtins.int enabled: builtins.bool """ Enable Bluetooth on the device @@ -1463,14 +1550,19 @@ class Config(google.protobuf.message.Message): """ Specified PIN for PairingMode.FixedPin """ + device_logging_enabled: builtins.bool + """ + Enables device (serial style logs) over Bluetooth + """ def __init__( self, *, enabled: builtins.bool = ..., mode: global___Config.BluetoothConfig.PairingMode.ValueType = ..., fixed_pin: builtins.int = ..., + device_logging_enabled: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... + def ClearField(self, field_name: typing.Literal["device_logging_enabled", b"device_logging_enabled", "enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... DEVICE_FIELD_NUMBER: builtins.int POSITION_FIELD_NUMBER: builtins.int diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 684b513..720478e 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xeb\x08\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xab\t\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,12 +31,12 @@ if _descriptor._USE_C_DESCRIPTORS == False: _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _globals['_HARDWAREMODEL']._serialized_start=5442 - _globals['_HARDWAREMODEL']._serialized_end=6573 - _globals['_CONSTANTS']._serialized_start=6575 - _globals['_CONSTANTS']._serialized_end=6619 - _globals['_CRITICALERRORCODE']._serialized_start=6622 - _globals['_CRITICALERRORCODE']._serialized_end=6860 + _globals['_HARDWAREMODEL']._serialized_start=5544 + _globals['_HARDWAREMODEL']._serialized_end=6739 + _globals['_CONSTANTS']._serialized_start=6741 + _globals['_CONSTANTS']._serialized_end=6785 + _globals['_CRITICALERRORCODE']._serialized_start=6788 + _globals['_CRITICALERRORCODE']._serialized_end=7026 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 @@ -74,25 +74,27 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_QUEUESTATUS']._serialized_start=3266 _globals['_QUEUESTATUS']._serialized_end=3346 _globals['_FROMRADIO']._serialized_start=3349 - _globals['_FROMRADIO']._serialized_end=4051 - _globals['_TORADIO']._serialized_start=4054 - _globals['_TORADIO']._serialized_end=4366 - _globals['_COMPRESSED']._serialized_start=4368 - _globals['_COMPRESSED']._serialized_end=4441 - _globals['_NEIGHBORINFO']._serialized_start=4444 - _globals['_NEIGHBORINFO']._serialized_end=4588 - _globals['_NEIGHBOR']._serialized_start=4590 - _globals['_NEIGHBOR']._serialized_end=4690 - _globals['_DEVICEMETADATA']._serialized_start=4693 - _globals['_DEVICEMETADATA']._serialized_end=5012 - _globals['_HEARTBEAT']._serialized_start=5014 - _globals['_HEARTBEAT']._serialized_end=5025 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5027 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5121 - _globals['_CHUNKEDPAYLOAD']._serialized_start=5123 - _globals['_CHUNKEDPAYLOAD']._serialized_end=5224 - _globals['_RESEND_CHUNKS']._serialized_start=5226 - _globals['_RESEND_CHUNKS']._serialized_end=5257 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5260 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=5439 + _globals['_FROMRADIO']._serialized_end=4102 + _globals['_FILEINFO']._serialized_start=4104 + _globals['_FILEINFO']._serialized_end=4153 + _globals['_TORADIO']._serialized_start=4156 + _globals['_TORADIO']._serialized_end=4468 + _globals['_COMPRESSED']._serialized_start=4470 + _globals['_COMPRESSED']._serialized_end=4543 + _globals['_NEIGHBORINFO']._serialized_start=4546 + _globals['_NEIGHBORINFO']._serialized_end=4690 + _globals['_NEIGHBOR']._serialized_start=4692 + _globals['_NEIGHBOR']._serialized_end=4792 + _globals['_DEVICEMETADATA']._serialized_start=4795 + _globals['_DEVICEMETADATA']._serialized_end=5114 + _globals['_HEARTBEAT']._serialized_start=5116 + _globals['_HEARTBEAT']._serialized_end=5127 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5129 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5223 + _globals['_CHUNKEDPAYLOAD']._serialized_start=5225 + _globals['_CHUNKEDPAYLOAD']._serialized_end=5326 + _globals['_RESEND_CHUNKS']._serialized_start=5328 + _globals['_RESEND_CHUNKS']._serialized_end=5359 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5362 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=5541 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 89b0a75..77880b4 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -121,6 +121,14 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk """ + RAK2560: _HardwareModel.ValueType # 22 + """ + RAK2560 Solar base station based on RAK4630 + """ + HELTEC_HRU_3601: _HardwareModel.ValueType # 23 + """ + Heltec HRU-3601: https://heltec.org/project/hru-3601/ + """ STATION_G1: _HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -295,6 +303,10 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS """ + HELTEC_CAPSULE_SENSOR_V3: _HardwareModel.ValueType # 65 + """ + Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -400,6 +412,14 @@ WIO_WM1110: HardwareModel.ValueType # 21 """ WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk """ +RAK2560: HardwareModel.ValueType # 22 +""" +RAK2560 Solar base station based on RAK4630 +""" +HELTEC_HRU_3601: HardwareModel.ValueType # 23 +""" +Heltec HRU-3601: https://heltec.org/project/hru-3601/ +""" STATION_G1: HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -574,6 +594,10 @@ RADIOMASTER_900_BANDIT_NANO: HardwareModel.ValueType # 64 RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS """ +HELTEC_CAPSULE_SENSOR_V3: HardwareModel.ValueType # 65 +""" +Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -2034,6 +2058,7 @@ class FromRadio(google.protobuf.message.Message): XMODEMPACKET_FIELD_NUMBER: builtins.int METADATA_FIELD_NUMBER: builtins.int MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int + FILEINFO_FIELD_NUMBER: builtins.int id: builtins.int """ The packet id, used to allow the phone to request missing read packets from the FIFO, @@ -2121,6 +2146,12 @@ class FromRadio(google.protobuf.message.Message): MQTT Client Proxy Message (device sending to client / phone for publishing to MQTT) """ + @property + def fileInfo(self) -> global___FileInfo: + """ + File system manifest messages + """ + def __init__( self, *, @@ -2138,13 +2169,42 @@ class FromRadio(google.protobuf.message.Message): xmodemPacket: meshtastic.protobuf.xmodem_pb2.XModem | None = ..., metadata: global___DeviceMetadata | None = ..., mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., + fileInfo: global___FileInfo | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage"] | None: ... + def HasField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage", "fileInfo"] | None: ... global___FromRadio = FromRadio +@typing.final +class FileInfo(google.protobuf.message.Message): + """ + Individual File info for the device + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FILE_NAME_FIELD_NUMBER: builtins.int + SIZE_BYTES_FIELD_NUMBER: builtins.int + file_name: builtins.str + """ + The fully qualified path of the file + """ + size_bytes: builtins.int + """ + The size of the file in bytes + """ + def __init__( + self, + *, + file_name: builtins.str = ..., + size_bytes: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["file_name", b"file_name", "size_bytes", b"size_bytes"]) -> None: ... + +global___FileInfo = FileInfo + @typing.final class ToRadio(google.protobuf.message.Message): """ diff --git a/meshtastic/protobuf/powermon_pb2.py b/meshtastic/protobuf/powermon_pb2.py new file mode 100644 index 0000000..4c34474 --- /dev/null +++ b/meshtastic/protobuf/powermon_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/powermon.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/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\x42\x63\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\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 + _globals['_POWERMON_STATE']._serialized_end=284 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/powermon_pb2.pyi b/meshtastic/protobuf/powermon_pb2.pyi new file mode 100644 index 0000000..5519b74 --- /dev/null +++ b/meshtastic/protobuf/powermon_pb2.pyi @@ -0,0 +1,97 @@ +""" +@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 + +@typing.final +class PowerMon(google.protobuf.message.Message): + """Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). + But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _State: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PowerMon._State.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CPU_DeepSleep: PowerMon._State.ValueType # 1 + CPU_LightSleep: PowerMon._State.ValueType # 2 + Vext1_On: PowerMon._State.ValueType # 4 + """ + The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only + occasionally. In cases where that rail has multiple devices on it we usually want to have logging on + the state of that rail as an independent record. + For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. + + The log messages will be short and complete (see PowerMon.Event in the protobufs for details). + something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. + (We use a bitmask for states so that if a log message gets lost it won't be fatal) + """ + Lora_RXOn: PowerMon._State.ValueType # 8 + Lora_TXOn: PowerMon._State.ValueType # 16 + Lora_RXActive: PowerMon._State.ValueType # 32 + BT_On: PowerMon._State.ValueType # 64 + LED_On: PowerMon._State.ValueType # 128 + Screen_On: PowerMon._State.ValueType # 256 + Screen_Drawing: PowerMon._State.ValueType # 512 + Wifi_On: PowerMon._State.ValueType # 1024 + GPS_Active: PowerMon._State.ValueType # 2048 + """ + GPS is actively trying to find our location + See GPSPowerState for more details + """ + + class State(_State, metaclass=_StateEnumTypeWrapper): + """Any significant power changing event in meshtastic should be tagged with a powermon state transition. + If you are making new meshtastic features feel free to add new entries at the end of this definition. + """ + + CPU_DeepSleep: PowerMon.State.ValueType # 1 + CPU_LightSleep: PowerMon.State.ValueType # 2 + Vext1_On: PowerMon.State.ValueType # 4 + """ + The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only + occasionally. In cases where that rail has multiple devices on it we usually want to have logging on + the state of that rail as an independent record. + For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. + + The log messages will be short and complete (see PowerMon.Event in the protobufs for details). + something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. + (We use a bitmask for states so that if a log message gets lost it won't be fatal) + """ + Lora_RXOn: PowerMon.State.ValueType # 8 + Lora_TXOn: PowerMon.State.ValueType # 16 + Lora_RXActive: PowerMon.State.ValueType # 32 + BT_On: PowerMon.State.ValueType # 64 + LED_On: PowerMon.State.ValueType # 128 + Screen_On: PowerMon.State.ValueType # 256 + Screen_Drawing: PowerMon.State.ValueType # 512 + Wifi_On: PowerMon.State.ValueType # 1024 + GPS_Active: PowerMon.State.ValueType # 2048 + """ + GPS is actively trying to find our location + See GPSPowerState for more details + """ + + def __init__( + self, + ) -> None: ... + +global___PowerMon = PowerMon diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 9c2cf4e..5a1188d 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xa6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant*\xdd\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xb6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,16 +21,18 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemet if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=1259 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=1608 + _globals['_TELEMETRYSENSORTYPE']._serialized_start=1339 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=1701 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=190 _globals['_ENVIRONMENTMETRICS']._serialized_start=193 - _globals['_ENVIRONMENTMETRICS']._serialized_end=487 - _globals['_POWERMETRICS']._serialized_start=490 - _globals['_POWERMETRICS']._serialized_end=630 - _globals['_AIRQUALITYMETRICS']._serialized_start=633 - _globals['_AIRQUALITYMETRICS']._serialized_end=952 - _globals['_TELEMETRY']._serialized_start=955 - _globals['_TELEMETRY']._serialized_end=1256 + _globals['_ENVIRONMENTMETRICS']._serialized_end=503 + _globals['_POWERMETRICS']._serialized_start=506 + _globals['_POWERMETRICS']._serialized_end=646 + _globals['_AIRQUALITYMETRICS']._serialized_start=649 + _globals['_AIRQUALITYMETRICS']._serialized_end=968 + _globals['_TELEMETRY']._serialized_start=971 + _globals['_TELEMETRY']._serialized_end=1272 + _globals['_NAU7802CONFIG']._serialized_start=1274 + _globals['_NAU7802CONFIG']._serialized_end=1336 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index aba51c8..fb0f4dd 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -123,6 +123,10 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) """ + NAU7802: _TelemetrySensorType.ValueType # 25 + """ + NAU7802 Scale Chip or compatible + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -229,6 +233,10 @@ DFROBOT_LARK: TelemetrySensorType.ValueType # 24 """ DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) """ +NAU7802: TelemetrySensorType.ValueType # 25 +""" +NAU7802 Scale Chip or compatible +""" global___TelemetrySensorType = TelemetrySensorType @typing.final @@ -299,6 +307,7 @@ class EnvironmentMetrics(google.protobuf.message.Message): UV_LUX_FIELD_NUMBER: builtins.int WIND_DIRECTION_FIELD_NUMBER: builtins.int WIND_SPEED_FIELD_NUMBER: builtins.int + WEIGHT_FIELD_NUMBER: builtins.int temperature: builtins.float """ Temperature measured @@ -357,6 +366,10 @@ class EnvironmentMetrics(google.protobuf.message.Message): """ Wind speed in m/s """ + weight: builtins.float + """ + Weight in KG + """ def __init__( self, *, @@ -374,8 +387,9 @@ class EnvironmentMetrics(google.protobuf.message.Message): uv_lux: builtins.float = ..., wind_direction: builtins.int = ..., wind_speed: builtins.float = ..., + weight: builtins.float = ..., ) -> None: ... - 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", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_speed", b"wind_speed"]) -> None: ... + 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", "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_speed", b"wind_speed"]) -> None: ... global___EnvironmentMetrics = EnvironmentMetrics @@ -574,3 +588,31 @@ class Telemetry(google.protobuf.message.Message): def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics"] | None: ... global___Telemetry = Telemetry + +@typing.final +class Nau7802Config(google.protobuf.message.Message): + """ + NAU7802 Telemetry configuration, for saving to flash + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ZEROOFFSET_FIELD_NUMBER: builtins.int + CALIBRATIONFACTOR_FIELD_NUMBER: builtins.int + zeroOffset: builtins.int + """ + The offset setting for the NAU7802 + """ + calibrationFactor: builtins.float + """ + The calibration factor for the NAU7802 + """ + def __init__( + self, + *, + zeroOffset: builtins.int = ..., + calibrationFactor: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["calibrationFactor", b"calibrationFactor", "zeroOffset", b"zeroOffset"]) -> None: ... + +global___Nau7802Config = Nau7802Config diff --git a/protobufs b/protobufs index 4da558d..a3030d5 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 4da558d0f73c46ef91b74431facee73c09affbfc +Subproject commit a3030d5ff187091c9fbbd08dd797cca5085736fe From 320bb30d29a87340efc84ebe2b7baa9082a986ba Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 11:12:02 -0700 Subject: [PATCH 070/248] Use .feather files as our long-term representation --- meshtastic/slog/arrow.py | 33 +++++++++++++++++++++++++++++++++ meshtastic/slog/slog.py | 8 ++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 225d3ce..eae77c2 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -1,6 +1,10 @@ """Utilities for Apache Arrow serialization.""" +import logging +import os + import pyarrow as pa +import pyarrow.feather as feather chunk_size = 1000 # disk writes are batched based on this number of rows @@ -42,3 +46,32 @@ class ArrowWriter: self.new_rows.append(row_dict) if len(self.new_rows) >= chunk_size: self._write() + + +class FeatherWriter(ArrowWriter): + """A smaller more interoperable version of arrow files. + Uses a temporary .arrow file (which could be huge) but converts to a much smaller (but still fast) + feather file. + """ + + def __init__(self, file_name: str): + super().__init__(file_name + ".arrow") + self.base_file_name = file_name + + def close(self): + super().close() + src_name = self.base_file_name + ".arrow" + dest_name = self.base_file_name + ".feather" + if os.path.getsize(src_name) == 0: + logging.warning(f"Discarding empty file: {src_name}") + os.remove(src_name) + else: + logging.info(f"Compressing log data into {dest_name}") + + # note: must use open_stream, not open_file/read_table because the streaming layout is different + # data = feather.read_table(src_name) + with pa.memory_map(src_name) as source: + array = pa.ipc.open_stream(source).read_all() + + # See https://stackoverflow.com/a/72406099 for more info and performance testing measurements + feather.write_feather(array, dest_name, compression="zstd") diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 49ed62c..8279130 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -17,7 +17,7 @@ from pubsub import pub # type: ignore[import-untyped] from meshtastic.mesh_interface import MeshInterface from meshtastic.powermon import PowerMeter -from .arrow import ArrowWriter +from .arrow import FeatherWriter @dataclass(init=False) @@ -54,7 +54,7 @@ class PowerLogger: def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.2) -> None: """Initialize the PowerLogger object.""" self.pMeter = pMeter - self.writer = ArrowWriter(file_path) + self.writer = FeatherWriter(file_path) self.interval = interval self.is_logging = True self.thread = threading.Thread( @@ -98,7 +98,7 @@ class StructuredLogger: client (MeshInterface): The MeshInterface object to monitor. """ self.client = client - self.writer = ArrowWriter(f"{dir_path}/slog.arrow") + self.writer = FeatherWriter(f"{dir_path}/slog") self.raw_file = open( # pylint: disable=consider-using-with f"{dir_path}/raw.txt", "w", encoding="utf8" ) @@ -175,7 +175,7 @@ class LogSet: self.power_logger: Optional[PowerLogger] = ( None if not power_meter - else PowerLogger(power_meter, f"{self.dir_name}/power.arrow") + else PowerLogger(power_meter, f"{self.dir_name}/power") ) # Store a lambda so we can find it again to unregister From 047a56d5540f4c8d9a176e49d1b5f7956d18df70 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 12:59:28 -0700 Subject: [PATCH 071/248] speed up file writing --- meshtastic/slog/arrow.py | 4 +++- meshtastic/slog/slog.py | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index eae77c2..a2d32e6 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -33,7 +33,8 @@ class ArrowWriter: """Write the new rows to the file.""" if len(self.new_rows) > 0: if self.schema is None: - self.schema = pa.Table.from_pylist(self.new_rows).schema + # only need to look at the first row to learn the schema + self.schema = pa.Table.from_pylist([self.new_rows[0]]).schema self.writer = pa.ipc.new_stream(self.sink, self.schema) self.writer.write_batch(pa.RecordBatch.from_pylist(self.new_rows)) @@ -75,3 +76,4 @@ class FeatherWriter(ArrowWriter): # See https://stackoverflow.com/a/72406099 for more info and performance testing measurements feather.write_feather(array, dest_name, compression="zstd") + os.remove(src_name) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 8279130..7f99d38 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -5,6 +5,7 @@ import logging import os import re import threading +import io import time from dataclasses import dataclass from datetime import datetime @@ -99,7 +100,7 @@ class StructuredLogger: """ self.client = client self.writer = FeatherWriter(f"{dir_path}/slog") - self.raw_file = open( # pylint: disable=consider-using-with + self.raw_file: Optional[io.TextIOWrapper] = open( # pylint: disable=consider-using-with f"{dir_path}/raw.txt", "w", encoding="utf8" ) self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) @@ -108,7 +109,9 @@ class StructuredLogger: """Stop logging.""" pub.unsubscribe(self.listener, TOPIC_MESHTASTIC_LOG_LINE) self.writer.close() - self.raw_file.close() # Close the raw.txt file + f = self.raw_file + self.raw_file = None # mark that we are shutting down + f.close() # Close the raw.txt file def _onLogMessage( self, line: str, interface: MeshInterface # pylint: disable=unused-argument @@ -134,7 +137,8 @@ class StructuredLogger: logging.warning(f"Failed to parse slog {line} with {d.format}") else: logging.warning(f"Unknown Structured Log: {line}") - self.raw_file.write(line + "\n") # Write the raw log + if self.raw_file: + self.raw_file.write(line + "\n") # Write the raw log class LogSet: From 715a085183f8d5c69e13ea76a18d364c4f24c7be Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 12:59:52 -0700 Subject: [PATCH 072/248] add more dataviz tooling --- poetry.lock | 664 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 5 + 2 files changed, 668 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 8e0d8cd..bf2c286 100644 --- a/poetry.lock +++ b/poetry.lock @@ -311,6 +311,17 @@ files = [ {file = "bleak_winrt-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:63130c11acfe75c504a79c01f9919e87f009f5e742bfc7b7a5c2a9c72bf591a7"}, ] +[[package]] +name = "blinker" +version = "1.8.2" +description = "Fast, simple object-to-object and broadcast signaling" +optional = false +python-versions = ">=3.8" +files = [ + {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, + {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, +] + [[package]] name = "certifi" version = "2024.6.2" @@ -527,6 +538,69 @@ traitlets = ">=4" [package.extras] test = ["pytest"] +[[package]] +name = "contourpy" +version = "1.2.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, +] + +[package.dependencies] +numpy = ">=1.20" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" version = "7.5.4" @@ -594,6 +668,87 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "dash" +version = "2.17.1" +description = "A Python framework for building reactive web-apps. Developed by Plotly." +optional = false +python-versions = ">=3.8" +files = [ + {file = "dash-2.17.1-py3-none-any.whl", hash = "sha256:3eefc9ac67003f93a06bc3e500cae0a6787c48e6c81f6f61514239ae2da414e4"}, + {file = "dash-2.17.1.tar.gz", hash = "sha256:ee2d9c319de5dcc1314085710b72cd5fa63ff994d913bf72979b7130daeea28e"}, +] + +[package.dependencies] +dash-core-components = "2.0.0" +dash-html-components = "2.0.0" +dash-table = "5.0.0" +Flask = ">=1.0.4,<3.1" +importlib-metadata = "*" +nest-asyncio = "*" +plotly = ">=5.0.0" +requests = "*" +retrying = "*" +setuptools = "*" +typing-extensions = ">=4.1.1" +Werkzeug = "<3.1" + +[package.extras] +celery = ["celery[redis] (>=5.1.2)", "redis (>=3.5.3)"] +ci = ["black (==22.3.0)", "dash-dangerously-set-inner-html", "dash-flow-example (==0.0.5)", "flake8 (==7.0.0)", "flaky (==3.8.1)", "flask-talisman (==1.0.0)", "jupyterlab (<4.0.0)", "mimesis (<=11.1.0)", "mock (==4.0.3)", "numpy (<=1.26.3)", "openpyxl", "orjson (==3.10.3)", "pandas (>=1.4.0)", "pyarrow", "pylint (==3.0.3)", "pytest-mock", "pytest-rerunfailures", "pytest-sugar (==0.9.6)", "pyzmq (==25.1.2)", "xlrd (>=2.0.1)"] +compress = ["flask-compress"] +dev = ["PyYAML (>=5.4.1)", "coloredlogs (>=15.0.1)", "fire (>=0.4.0)"] +diskcache = ["diskcache (>=5.2.1)", "multiprocess (>=0.70.12)", "psutil (>=5.8.0)"] +testing = ["beautifulsoup4 (>=4.8.2)", "cryptography", "dash-testing-stub (>=0.0.2)", "lxml (>=4.6.2)", "multiprocess (>=0.70.12)", "percy (>=2.0.2)", "psutil (>=5.8.0)", "pytest (>=6.0.2)", "requests[security] (>=2.21.0)", "selenium (>=3.141.0,<=4.2.0)", "waitress (>=1.4.4)"] + +[[package]] +name = "dash-core-components" +version = "2.0.0" +description = "Core component suite for Dash" +optional = false +python-versions = "*" +files = [ + {file = "dash_core_components-2.0.0-py3-none-any.whl", hash = "sha256:52b8e8cce13b18d0802ee3acbc5e888cb1248a04968f962d63d070400af2e346"}, + {file = "dash_core_components-2.0.0.tar.gz", hash = "sha256:c6733874af975e552f95a1398a16c2ee7df14ce43fa60bb3718a3c6e0b63ffee"}, +] + +[[package]] +name = "dash-html-components" +version = "2.0.0" +description = "Vanilla HTML components for Dash" +optional = false +python-versions = "*" +files = [ + {file = "dash_html_components-2.0.0-py3-none-any.whl", hash = "sha256:b42cc903713c9706af03b3f2548bda4be7307a7cf89b7d6eae3da872717d1b63"}, + {file = "dash_html_components-2.0.0.tar.gz", hash = "sha256:8703a601080f02619a6390998e0b3da4a5daabe97a1fd7a9cebc09d015f26e50"}, +] + +[[package]] +name = "dash-table" +version = "5.0.0" +description = "Dash table" +optional = false +python-versions = "*" +files = [ + {file = "dash_table-5.0.0-py3-none-any.whl", hash = "sha256:19036fa352bb1c11baf38068ec62d172f0515f73ca3276c79dee49b95ddc16c9"}, + {file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"}, +] + [[package]] name = "dbus-fast" version = "2.21.3" @@ -758,6 +913,94 @@ files = [ [package.extras] devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] +[[package]] +name = "flask" +version = "3.0.3" +description = "A simple framework for building complex web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"}, + {file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"}, +] + +[package.dependencies] +blinker = ">=1.6.2" +click = ">=8.1.3" +importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} +itsdangerous = ">=2.1.2" +Jinja2 = ">=3.1.2" +Werkzeug = ">=3.0.0" + +[package.extras] +async = ["asgiref (>=3.2)"] +dotenv = ["python-dotenv"] + +[[package]] +name = "fonttools" +version = "4.53.0" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, + {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, + {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, + {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, + {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, + {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, + {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, + {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, + {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, + {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, + {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, + {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, + {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, + {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, + {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, + {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, + {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, + {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, + {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, + {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, + {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, + {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, + {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, + {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, + {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, + {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, + {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, + {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, + {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, + {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, + {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, + {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, + {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, + {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, + {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, + {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, + {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, + {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, + {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, + {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, + {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, + {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "fqdn" version = "1.5.1" @@ -888,6 +1131,24 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke perf = ["ipython"] test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +[[package]] +name = "importlib-resources" +version = "6.4.0" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, + {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -932,6 +1193,29 @@ pyqt5 = ["pyqt5"] pyside6 = ["pyside6"] test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] +[[package]] +name = "ipympl" +version = "0.9.4" +description = "Matplotlib Jupyter Extension" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ipympl-0.9.4-py3-none-any.whl", hash = "sha256:5b0c08c6f4f6ea655ba58239363457c10fb921557f5038c1a46db4457d6d6b0e"}, + {file = "ipympl-0.9.4.tar.gz", hash = "sha256:cfb53c5b4fcbcee6d18f095eecfc6c6c474303d5b744e72cc66e7a2804708907"}, +] + +[package.dependencies] +ipython = "<9" +ipython-genutils = "*" +ipywidgets = ">=7.6.0,<9" +matplotlib = ">=3.4.0,<4" +numpy = "*" +pillow = "*" +traitlets = "<6" + +[package.extras] +docs = ["myst-nb", "sphinx (>=1.5)", "sphinx-book-theme", "sphinx-copybutton", "sphinx-thebe", "sphinx-togglebutton"] + [[package]] name = "ipython" version = "8.18.1" @@ -969,6 +1253,38 @@ qtconsole = ["qtconsole"] test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] +[[package]] +name = "ipython-genutils" +version = "0.2.0" +description = "Vestigial utilities from IPython" +optional = false +python-versions = "*" +files = [ + {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, + {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, +] + +[[package]] +name = "ipywidgets" +version = "8.1.3" +description = "Jupyter interactive widgets" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"}, + {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"}, +] + +[package.dependencies] +comm = ">=0.1.3" +ipython = ">=6.1.0" +jupyterlab-widgets = ">=3.0.11,<3.1.0" +traitlets = ">=4.3.1" +widgetsnbextension = ">=4.0.11,<4.1.0" + +[package.extras] +test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] + [[package]] name = "isoduration" version = "20.11.0" @@ -997,6 +1313,17 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "itsdangerous" +version = "2.2.0" +description = "Safely pass data to untrusted environments and back." +optional = false +python-versions = ">=3.8" +files = [ + {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, + {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, +] + [[package]] name = "jedi" version = "0.19.1" @@ -1308,6 +1635,130 @@ docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pyd openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] +[[package]] +name = "jupyterlab-widgets" +version = "3.0.11" +description = "Jupyter interactive widgets for JupyterLab" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"}, + {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"}, +] + +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + [[package]] name = "macholib" version = "1.16.3" @@ -1428,6 +1879,59 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "matplotlib" +version = "3.9.0" +description = "Python plotting package" +optional = false +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, + {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, + {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, + {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, + {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, + {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, + {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, + {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, + {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, + {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, + {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, + {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, + {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, + {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, + {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, + {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, + {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, + {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, + {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, + {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, + {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, + {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, + {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, + {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, + {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "matplotlib-inline" version = "0.1.7" @@ -1813,6 +2317,92 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" +[[package]] +name = "pillow" +version = "10.3.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, + {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, + {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, + {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, + {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, + {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, + {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, + {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, + {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, + {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, + {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, + {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, + {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, + {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, + {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, + {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + [[package]] name = "platformdirs" version = "4.2.2" @@ -1829,6 +2419,21 @@ docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx- test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] type = ["mypy (>=1.8)"] +[[package]] +name = "plotly" +version = "5.22.0" +description = "An open-source, interactive data visualization library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "plotly-5.22.0-py3-none-any.whl", hash = "sha256:68fc1901f098daeb233cc3dd44ec9dc31fb3ca4f4e53189344199c43496ed006"}, + {file = "plotly-5.22.0.tar.gz", hash = "sha256:859fdadbd86b5770ae2466e542b761b247d1c6b49daed765b95bb8c7063e7469"}, +] + +[package.dependencies] +packaging = "*" +tenacity = ">=6.2.0" + [[package]] name = "pluggy" version = "1.5.0" @@ -2581,6 +3186,20 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "retrying" +version = "1.3.4" +description = "Retrying" +optional = false +python-versions = "*" +files = [ + {file = "retrying-1.3.4-py3-none-any.whl", hash = "sha256:8cc4d43cb8e1125e0ff3344e9de678fefd85db3b750b81b2240dc0183af37b35"}, + {file = "retrying-1.3.4.tar.gz", hash = "sha256:345da8c5765bd982b1d1915deb9102fd3d1f7ad16bd84a9700b85f64d24e8f3e"}, +] + +[package.dependencies] +six = ">=1.7.0" + [[package]] name = "rfc3339-validator" version = "0.1.4" @@ -2842,6 +3461,21 @@ files = [ [package.extras] widechars = ["wcwidth"] +[[package]] +name = "tenacity" +version = "8.4.2" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, + {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + [[package]] name = "terminado" version = "0.18.1" @@ -3102,6 +3736,34 @@ docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] +[[package]] +name = "werkzeug" +version = "3.0.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, + {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "widgetsnbextension" +version = "4.0.11" +description = "Jupyter interactive widgets for Jupyter Notebook" +optional = false +python-versions = ">=3.7" +files = [ + {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"}, + {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"}, +] + [[package]] name = "winrt-runtime" version = "2.0.0b1" @@ -3341,4 +4003,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "c06a63c0dc330add8ff30c22a1c351f31e90a3cdb71afce7ce4644feb48c1038" +content-hash = "895a19621735918ee08874535bea6aabd349900ecc71c88ed4f3474dc935932a" diff --git a/pyproject.toml b/pyproject.toml index 698ae71..609c1f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,11 @@ types-tabulate = "^0.9.0.20240106" types-requests = "^2.31.0.20240406" types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" +matplotlib = "^3.9.0" +ipympl = "^0.9.4" +ipywidgets = "^8.1.3" +jupyterlab-widgets = "^3.0.11" +dash = "^2.17.1" [tool.poetry.extras] tunnel = ["pytap2"] From 62ce8eaa77b289b2736acdb829cb2b0029a8ecf9 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 13:52:54 -0700 Subject: [PATCH 073/248] fix code coverage CI false alarm? --- .coveragerc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index 5171a00..c9d62bb 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,5 @@ [run] -omit = meshtastic/*_pb2.py,meshtastic/tests/*.py,meshtastic/test.py +omit = meshtastic/protobuf/*_pb2.py,meshtastic/tests/*.py,meshtastic/test.py [report] exclude_lines = From 67bb6665f2af3070e27fb276e358a1a24b45506d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 15:29:18 -0700 Subject: [PATCH 074/248] the stock PPK2 API is super inefficient, remove lots of buffering --- meshtastic/powermon/ppk2.py | 58 ++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 53285fa..3831faf 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -31,12 +31,22 @@ class PPK2PowerSupply(PowerSupply): else: portName = devs[0] - self.r = r = ppk2_api.PPK2_MP(portName) # serial port will be different for you + self.current_max = 0 + self.current_min = 0 + self.current_sum = 0 + self.current_num_samples = 0 + + # for tracking avera data read length (to determine if we are sleeping efficiently in measurement_loop) + self.total_data_len = 0 + self.num_data_reads = 0 + self.max_data_len = 0 + + self.r = r = ppk2_api.PPK2_API(portName) # serial port will be different for you r.get_modifiers() self.r.start_measuring() # send command to ppk2 - self.current_measurements = [0.0] # reset current measurements to 0mA self.measuring = True + self.reset_measurements() self.measurement_thread = threading.Thread( target=self.measurement_loop, daemon=True, name="ppk2 measurement" @@ -50,32 +60,54 @@ class PPK2PowerSupply(PowerSupply): def measurement_loop(self): """Endless measurement loop will run in a thread.""" while self.measuring: + # always reads 4096 bytes, even if there is no new samples - or possibly the python single thread (because of global interpreter lock) + # is always behind and thefore we are inherently dropping samples semi randomly!!! read_data = self.r.get_data() - if read_data != b"": + if read_data != b'': samples, _ = self.r.get_samples(read_data) - self.current_measurements += samples - time.sleep(0.001) # FIXME figure out correct sleep duration + + # update invariants + self.current_max = max(self.current_max, max(samples)) + self.current_min = min(self.current_min, min(samples)) + self.current_sum += sum(samples) + self.current_num_samples += len(samples) + # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") + + self.num_data_reads += 1 + self.total_data_len += len(read_data) + self.max_data_len = max(self.max_data_len, len(read_data)) + + time.sleep(0.01) # FIXME figure out correct sleep duration def get_min_current_mA(self): """Returns max current in mA (since last call to this method).""" - return min(self.current_measurements) / 1000 + return self.current_min / 1000 def get_max_current_mA(self): """Returns max current in mA (since last call to this method).""" - return max(self.current_measurements) / 1000 + return self.current_max / 1000 def get_average_current_mA(self): """Returns average current in mA (since last call to this method).""" - average_current_mA = ( - sum(self.current_measurements) / len(self.current_measurements) - ) / 1000 # measurements are in microamperes, divide by 1000 - - return average_current_mA + if self.current_num_samples == 0: + return 0 + else: + return self.current_sum / self.current_num_samples / 1000 # measurements are in microamperes, divide by 1000 def reset_measurements(self): """Reset current measurements.""" # Use the last reading as the new only reading (to ensure we always have a valid current reading) - self.current_measurements = [ self.current_measurements[-1] ] + self.current_max = 0 + self.current_min = 0 + self.current_sum = 0 + self.current_num_samples = 0 + + #if self.num_data_reads: + # logging.debug(f"max data len = {self.max_data_len},avg {self.total_data_len/self.num_data_reads}, num reads={self.num_data_reads}") + # Summary stats for performance monitoring + self.num_data_reads = 0 + self.total_data_len = 0 + self.max_data_len = 0 def close(self) -> None: """Close the power meter.""" From 229454656092437aee6200bdef25a0c6b5ca3201 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 16:43:14 -0700 Subject: [PATCH 075/248] fix bogus high current reading on first ppk2 read --- meshtastic/powermon/ppk2.py | 53 ++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 3831faf..1e2504d 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -31,6 +31,7 @@ class PPK2PowerSupply(PowerSupply): else: portName = devs[0] + self.measuring = False self.current_max = 0 self.current_min = 0 self.current_sum = 0 @@ -41,20 +42,15 @@ class PPK2PowerSupply(PowerSupply): self.num_data_reads = 0 self.max_data_len = 0 - self.r = r = ppk2_api.PPK2_API(portName) # serial port will be different for you + self.r = r = ppk2_api.PPK2_API( + portName + ) # serial port will be different for you r.get_modifiers() - self.r.start_measuring() # send command to ppk2 - self.measuring = True - self.reset_measurements() - self.measurement_thread = threading.Thread( target=self.measurement_loop, daemon=True, name="ppk2 measurement" ) - self.measurement_thread.start() - logging.info("Connected to Power Profiler Kit II (PPK2)") - super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works def measurement_loop(self): @@ -63,15 +59,20 @@ class PPK2PowerSupply(PowerSupply): # always reads 4096 bytes, even if there is no new samples - or possibly the python single thread (because of global interpreter lock) # is always behind and thefore we are inherently dropping samples semi randomly!!! read_data = self.r.get_data() - if read_data != b'': + if read_data != b"": samples, _ = self.r.get_samples(read_data) # update invariants - self.current_max = max(self.current_max, max(samples)) - self.current_min = min(self.current_min, min(samples)) - self.current_sum += sum(samples) - self.current_num_samples += len(samples) - # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") + if len(samples) > 0: + if self.current_num_samples == 0: + self.current_min = samples[ + 0 + ] # we need at least one sample to get an initial min + self.current_max = max(self.current_max, max(samples)) + self.current_min = min(self.current_min, min(samples)) + self.current_sum += sum(samples) + self.current_num_samples += len(samples) + # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") self.num_data_reads += 1 self.total_data_len += len(read_data) @@ -92,7 +93,9 @@ class PPK2PowerSupply(PowerSupply): if self.current_num_samples == 0: return 0 else: - return self.current_sum / self.current_num_samples / 1000 # measurements are in microamperes, divide by 1000 + return ( + self.current_sum / self.current_num_samples / 1000 + ) # measurements are in microamperes, divide by 1000 def reset_measurements(self): """Reset current measurements.""" @@ -102,7 +105,7 @@ class PPK2PowerSupply(PowerSupply): self.current_sum = 0 self.current_num_samples = 0 - #if self.num_data_reads: + # if self.num_data_reads: # logging.debug(f"max data len = {self.max_data_len},avg {self.total_data_len/self.num_data_reads}, num reads={self.num_data_reads}") # Summary stats for performance monitoring self.num_data_reads = 0 @@ -124,13 +127,25 @@ class PPK2PowerSupply(PowerSupply): ) # set source voltage in mV BEFORE setting source mode # Note: source voltage must be set even if we are using the amp meter mode - if ( - not s - ): # min power outpuf of PPK2. If less than this assume we want just meter mode. + # must be after setting source voltage and before setting mode + self.r.start_measuring() # send command to ppk2 + + if not s: # min power outpuf of PPK2. If less than this assume we want just meter mode. self.r.use_ampere_meter() else: self.r.use_source_meter() # set source meter mode + if not self.measurement_thread.is_alive(): + self.measuring = True + self.reset_measurements() + + # We can't start reading from the thread until vdd is set, so start running the thread now + self.measurement_thread.start() + time.sleep( + 0.2 + ) # FIXME - crufty way to ensure we do one set of reads to discard bogus fake power readings in the FIFO + self.reset_measurements() + def powerOn(self): """Power on the supply.""" self.r.toggle_DUT_power("ON") From c9351236e62a6c61f888c442cbf9c4343492e65d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 26 Jun 2024 17:28:55 -0700 Subject: [PATCH 076/248] blacklist hantek oscilliscope --- meshtastic/util.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index ef12344..c95aef0 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -25,14 +25,16 @@ from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version """Some devices such as a seger jlink or st-link we never want to accidentally open -0x1915 NordicSemi (PPK2) + 1915 NordicSemi (PPK2) + 0925 Lakeview Research Saleae Logic (logic analyzer) +04b4:602a Cypress Semiconductor Corp. Hantek DSO-6022BL (oscilloscope) """ -blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915]) +blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915, 0x0925]) """Some devices are highly likely to be meshtastic. 0x239a RAK4631 0x303a Heltec tracker""" -whitelistVids = dict.fromkeys([0x239a, 0x303a]) +whitelistVids = dict.fromkeys([0x239a, 0x303a, 0x04b4]) def quoteBooleans(a_string): From 960e32fa4b32c76eb5e6da25cdf329f2133078f9 Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Tue, 28 May 2024 10:03:04 +0200 Subject: [PATCH 077/248] Clarify licensing in compliance with https://reuse.software/ The license was changed on 1 Nov 2022 in https://github.com/meshtastic/python/pull/392 --- .reuse/dep5 | 64 +++++++++++ LICENSE.txt | 202 --------------------------------- LICENSES/GPL-3.0-only.txt | 232 ++++++++++++++++++++++++++++++++++++++ README.md | 1 + 4 files changed, 297 insertions(+), 202 deletions(-) create mode 100644 .reuse/dep5 delete mode 100644 LICENSE.txt create mode 100644 LICENSES/GPL-3.0-only.txt diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000..22b8e05 --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,64 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Meshtastic Python +Upstream-Contact: Various Authors +Source: https://github.com/meshtastic/python + +Files: * +Copyright: + 2020-2020 Nils Werner + 2020-2020 Paul Vivier + 2020-2020 Tim Gunter + 2020-2021 Charles Crossan + 2020-2021 IZ1IVA + 2020-2022 Jm Casler + 2020-2024 geeksville + 2021-2021 Andrew Cabey + 2021-2021 dylan + 2021-2021 Fabian Affolter + 2021-2021 Foster Irwin + 2021-2021 Manuel Giolo + 2021-2021 meehow + 2021-2021 srichs + 2021-2021 ChuckNorrison + 2021-2021 Aivaras-s + 2021-2021 a-f-G-U-C + 2021-2021 + 2021-2021 jdstroy + 2021-2021 linagee + 2021-2021 Simonas + 2021-2022 + 2021-2023 Sacha Weatherstone + 2021-2024 Ben Meadors + 2022-2022 Balázs Kelemen <10376327+prampec + 2022-2022 + 2022-2022 + 2022-2022 + 2022-2022 + 2022-2022 + 2022-2022 Rohan King + 2022-2022 Tom Douile + 2022-2023 Thomas Göttgens + 2022-2024 thijs@havinga.eu> + 2023-2023 Eli Schleifer + 2023-2023 Manuel + 2023-2023 Marek Küthe + 2023-2023 + 2023-2023 + 2023-2023 + 2023-2023 luzpaz + 2023-2023 + 2023-2023 Toby Murray + 2023-2024 Brad Midgley + 2024-2024 Ian McEwen + 2024-2024 John Hollowell + 2024-2024 Jonathan Bennett + 2024-2024 + 2024-2024 + 2024-2024 + 2024-2024 + 2024-2024 rc14193 + 2024-2024 Steve Holden + 2024-2024 Thomas Herrmann + 2024-2024 Timothy Harder + 2024-2024 Wolfgang Nagele +License: GPL-3.0-only diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/LICENSES/GPL-3.0-only.txt b/LICENSES/GPL-3.0-only.txt new file mode 100644 index 0000000..f6cdd22 --- /dev/null +++ b/LICENSES/GPL-3.0-only.txt @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/README.md b/README.md index 6d7d890..0482acc 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![CI](https://img.shields.io/github/actions/workflow/status/meshtastic/python/ci.yml?branch=master&label=actions&logo=github&color=yellow)](https://github.com/meshtastic/python/actions/workflows/ci.yml) [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/python)](https://cla-assistant.io/meshtastic/python) [![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-LGPL%20v3-blue.svg) ## Overview From 5b55e3b877af8441b01282ac32c2512020622d5c Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Thu, 27 Jun 2024 19:35:43 +0200 Subject: [PATCH 078/248] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0482acc..dd4ab5e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![CI](https://img.shields.io/github/actions/workflow/status/meshtastic/python/ci.yml?branch=master&label=actions&logo=github&color=yellow)](https://github.com/meshtastic/python/actions/workflows/ci.yml) [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/python)](https://cla-assistant.io/meshtastic/python) [![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-LGPL%20v3-blue.svg) +![GPL-3.0](https://img.shields.io/badge/License-GPL%20v3-blue.svg) ## Overview From 119be810009154929c3eed6c076d2f945939b3cd Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 27 Jun 2024 16:36:31 -0700 Subject: [PATCH 079/248] PowerStress WIP --- .vscode/launch.json | 8 ++ .vscode/settings.json | 2 + meshtastic/__init__.py | 4 + meshtastic/__main__.py | 26 +++--- meshtastic/powermon/__init__.py | 1 + meshtastic/powermon/stress.py | 78 +++++++++++++++++ meshtastic/protobuf/portnums_pb2.py | 4 +- meshtastic/protobuf/portnums_pb2.pyi | 8 ++ meshtastic/protobuf/powermon_pb2.py | 6 +- meshtastic/protobuf/powermon_pb2.pyi | 124 +++++++++++++++++++++++++++ protobufs | 2 +- 11 files changed, 248 insertions(+), 15 deletions(-) create mode 100644 meshtastic/powermon/stress.py diff --git a/.vscode/launch.json b/.vscode/launch.json index cef11f4..6d4b9b5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -182,6 +182,14 @@ "justMyCode": false, "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-wait", "--power-voltage", "3.3", "--noproto", "--seriallog", "stdout"] }, + { + "name": "meshtastic stress ppk2", + "type": "debugpy", + "request": "launch", + "module": "meshtastic", + "justMyCode": false, + "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog", "stdout"] + }, { "name": "meshtastic test", "type": "debugpy", diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b0d16e..8fbd0a0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,7 +4,9 @@ "boardid", "Meshtastic", "milliwatt", + "portnums", "powermon", + "POWERSTRESS", "pyarrow", "TORADIO", "Vids" diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 75508d0..f4d91fd 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -97,6 +97,7 @@ from .protobuf import ( remote_hardware_pb2, storeforward_pb2, telemetry_pb2, + powermon_pb2 ) from . import ( util, @@ -229,6 +230,9 @@ protocols = { portnums_pb2.PortNum.TRACEROUTE_APP: KnownProtocol( "traceroute", mesh_pb2.RouteDiscovery ), + portnums_pb2.PortNum.POWERSTRESS_APP: KnownProtocol( + "powerstress", powermon_pb2.PowerStressMessage + ), portnums_pb2.PortNum.WAYPOINT_APP: KnownProtocol("waypoint", mesh_pb2.Waypoint), portnums_pb2.PortNum.PAXCOUNTER_APP: KnownProtocol("paxcounter", paxcount_pb2.Paxcount), portnums_pb2.PortNum.STORE_FORWARD_APP: KnownProtocol("storeforward", storeforward_pb2.StoreAndForward), diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index aa8f90d..f479009 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -11,6 +11,7 @@ import os import platform import sys import time +from typing import Optional import pyqrcode # type: ignore[import-untyped] import yaml @@ -25,9 +26,11 @@ from meshtastic import remote_hardware, BROADCAST_ADDR from meshtastic.version import get_active_version from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply, SimPowerSupply +from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply, SimPowerSupply, PowerStress, PowerMeter from meshtastic.slog import LogSet +meter: Optional[PowerMeter] = None + def onReceive(packet, interface): """Callback invoked when a packet arrives""" args = mt_config.args @@ -849,6 +852,15 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) + if args.slog_out: + # Setup loggers + global meter + LogSet(interface, args.slog_out if args.slog_out != 'default' else None, meter) + + if args.power_stress: + stress = PowerStress(interface) + stress.run() + if args.listen: closeNow = False @@ -989,6 +1001,7 @@ def export_config(interface): def create_power_meter(): """Setup the power meter.""" + global meter args = mt_config.args meter = None # assume no power meter if args.power_riden: @@ -1009,7 +1022,6 @@ def create_power_meter(): if args.power_wait: input("Powered on, press enter to continue...") - return meter def common(): """Shared code for all of our command line wrappers.""" @@ -1029,7 +1041,7 @@ def common(): meshtastic.util.support_info() meshtastic.util.our_exit("", 0) - meter = create_power_meter() + create_power_meter() if args.ch_index is not None: channelIndex = int(args.ch_index) @@ -1120,11 +1132,6 @@ def common(): # We assume client is fully connected now onConnected(client) - log_set = None - if args.slog_out: - # Setup loggers - log_set = LogSet(client, args.slog_out if args.slog_out != 'default' else None, meter) - have_tunnel = platform.system() == "Linux" if ( args.noproto or args.reply or (have_tunnel and args.tunnel) or args.listen @@ -1135,9 +1142,6 @@ def common(): except KeyboardInterrupt: logging.info("Exiting due to keyboard interrupt") - if log_set: - log_set.close() - # don't call exit, background threads might be running still # sys.exit(0) diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index a8f578f..aefc8ae 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -4,3 +4,4 @@ from .power_supply import PowerError, PowerMeter, PowerSupply from .ppk2 import PPK2PowerSupply from .riden import RidenPowerSupply from .sim import SimPowerSupply +from .stress import PowerStress \ No newline at end of file diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py new file mode 100644 index 0000000..b847e12 --- /dev/null +++ b/meshtastic/powermon/stress.py @@ -0,0 +1,78 @@ +"""Power stress testing support. +""" +import logging +import time + +from pubsub import pub # type: ignore[import-untyped] + +from meshtastic.protobuf import portnums_pb2 +from meshtastic.protobuf.powermon_pb2 import PowerStressMessage + + +def onPowerStressResponse(packet, interface): + """Delete me? FIXME""" + logging.debug(f"packet:{packet} interface:{interface}") + # interface.gotResponse = True + + +class PowerStressClient: + """ + The client stub for talking to the firmware PowerStress module. + """ + + def __init__(self, iface, node_id = None): + """ + Create a new PowerStressClient instance. + + iface is the already open MeshInterface instance + """ + self.iface = iface + + if not node_id: + node_id = iface.myInfo.my_node_num + + self.node_id = node_id + # No need to subscribe - because we + # pub.subscribe(onGPIOreceive, "meshtastic.receive.powerstress") + + def sendPowerStress( + self, cmd: PowerStressMessage.Opcode.ValueType, num_seconds: float = 0.0, onResponse=None + ): + r = PowerStressMessage() + r.cmd = cmd + r.num_seconds = num_seconds + + return self.iface.sendData( + r, + self.node_id, + portnums_pb2.POWERSTRESS_APP, + wantAck=True, + wantResponse=False, + onResponse=onResponse, + onResponseAckPermitted=True + ) + +class PowerStress: + """Walk the UUT through a set of power states so we can capture repeatable power consumption measurements.""" + + def __init__(self, iface): + self.client = PowerStressClient(iface) + + + def run(self): + """Run the power stress test.""" + # Send the power stress command + gotAck = False + + def onResponse(packet, interface): + nonlocal gotAck + gotAck = True + + logging.info("Starting power stress test, attempting to contact UUT...") + self.client.sendPowerStress(PowerStressMessage.PRINT_INFO, onResponse=onResponse) + + # Wait for the response + while not gotAck: + time.sleep(0.1) + + logging.info("Power stress test complete.") \ No newline at end of file diff --git a/meshtastic/protobuf/portnums_pb2.py b/meshtastic/protobuf/portnums_pb2.py index bb0cd07..7f851eb 100644 --- a/meshtastic/protobuf/portnums_pb2.py +++ b/meshtastic/protobuf/portnums_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\x8d\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\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\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42]\n\x13\x63om.geeksville.meshB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xa2\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\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) @@ -22,5 +22,5 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_PORTNUM']._serialized_start=60 - _globals['_PORTNUM']._serialized_end=585 + _globals['_PORTNUM']._serialized_end=606 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/portnums_pb2.pyi b/meshtastic/protobuf/portnums_pb2.pyi index fda2e89..3c7546c 100644 --- a/meshtastic/protobuf/portnums_pb2.pyi +++ b/meshtastic/protobuf/portnums_pb2.pyi @@ -171,6 +171,10 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy """ Provides unencrypted information about a node for consumption by a map via MQTT """ + POWERSTRESS_APP: _PortNum.ValueType # 74 + """ + PowerStress based monitoring support (for automated power consumption testing) + """ PRIVATE_APP: _PortNum.ValueType # 256 """ Private applications should use portnums >= 256. @@ -352,6 +356,10 @@ MAP_REPORT_APP: PortNum.ValueType # 73 """ Provides unencrypted information about a node for consumption by a map via MQTT """ +POWERSTRESS_APP: PortNum.ValueType # 74 +""" +PowerStress based monitoring support (for automated power consumption testing) +""" PRIVATE_APP: PortNum.ValueType # 256 """ Private applications should use portnums >= 256. diff --git a/meshtastic/protobuf/powermon_pb2.py b/meshtastic/protobuf/powermon_pb2.py index 4c34474..326a66f 100644 --- a/meshtastic/protobuf/powermon_pb2.py +++ b/meshtastic/protobuf/powermon_pb2.py @@ -13,7 +13,7 @@ _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\x42\x63\n\x13\x63om.geeksville.meshB\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) @@ -25,4 +25,8 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_POWERMON']._serialized_end=284 _globals['_POWERMON_STATE']._serialized_start=73 _globals['_POWERMON_STATE']._serialized_end=284 + _globals['_POWERSTRESSMESSAGE']._serialized_start=287 + _globals['_POWERSTRESSMESSAGE']._serialized_end=679 + _globals['_POWERSTRESSMESSAGE_OPCODE']._serialized_start=392 + _globals['_POWERSTRESSMESSAGE_OPCODE']._serialized_end=679 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/powermon_pb2.pyi b/meshtastic/protobuf/powermon_pb2.pyi index 5519b74..6c51a28 100644 --- a/meshtastic/protobuf/powermon_pb2.pyi +++ b/meshtastic/protobuf/powermon_pb2.pyi @@ -95,3 +95,127 @@ class PowerMon(google.protobuf.message.Message): ) -> None: ... global___PowerMon = PowerMon + +@typing.final +class PowerStressMessage(google.protobuf.message.Message): + """ + PowerStress testing support via the C++ PowerStress module + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Opcode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _OpcodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PowerStressMessage._Opcode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: PowerStressMessage._Opcode.ValueType # 0 + """ + Unset/unused + """ + PRINT_INFO: PowerStressMessage._Opcode.ValueType # 1 + """Print board version slog and send an ack that we are alive and ready to process commands""" + FORCE_QUIET: PowerStressMessage._Opcode.ValueType # 2 + """Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation)""" + END_QUIET: PowerStressMessage._Opcode.ValueType # 3 + """Stop powerstress processing - probably by just rebooting the board""" + SCREEN_ON: PowerStressMessage._Opcode.ValueType # 16 + """Turn the screen on""" + SCREEN_OFF: PowerStressMessage._Opcode.ValueType # 17 + """Turn the screen off""" + CPU_IDLE: PowerStressMessage._Opcode.ValueType # 32 + """Let the CPU run but we assume mostly idling for num_seconds""" + CPU_DEEPSLEEP: PowerStressMessage._Opcode.ValueType # 33 + """Force deep sleep for FIXME seconds""" + CPU_FULLON: PowerStressMessage._Opcode.ValueType # 34 + """Spin the CPU as fast as possible for num_seconds""" + LED_ON: PowerStressMessage._Opcode.ValueType # 48 + """Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes)""" + LED_OFF: PowerStressMessage._Opcode.ValueType # 49 + """Force the LED off for num_seconds""" + LORA_OFF: PowerStressMessage._Opcode.ValueType # 64 + """Completely turn off the LORA radio for num_seconds""" + LORA_TX: PowerStressMessage._Opcode.ValueType # 65 + """Send Lora packets for num_seconds""" + LORA_RX: PowerStressMessage._Opcode.ValueType # 66 + """Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel)""" + BT_OFF: PowerStressMessage._Opcode.ValueType # 80 + """Turn off the BT radio for num_seconds""" + BT_ON: PowerStressMessage._Opcode.ValueType # 81 + """Turn on the BT radio for num_seconds""" + WIFI_OFF: PowerStressMessage._Opcode.ValueType # 96 + """Turn off the WIFI radio for num_seconds""" + WIFI_ON: PowerStressMessage._Opcode.ValueType # 97 + """Turn on the WIFI radio for num_seconds""" + GPS_OFF: PowerStressMessage._Opcode.ValueType # 112 + """Turn off the GPS radio for num_seconds""" + GPS_ON: PowerStressMessage._Opcode.ValueType # 113 + """Turn on the GPS radio for num_seconds""" + + class Opcode(_Opcode, metaclass=_OpcodeEnumTypeWrapper): + """ + What operation would we like the UUT to perform. + note: senders should probably set want_response in their request packets, so that they can know when the state + machine has started processing their request + """ + + UNSET: PowerStressMessage.Opcode.ValueType # 0 + """ + Unset/unused + """ + PRINT_INFO: PowerStressMessage.Opcode.ValueType # 1 + """Print board version slog and send an ack that we are alive and ready to process commands""" + FORCE_QUIET: PowerStressMessage.Opcode.ValueType # 2 + """Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation)""" + END_QUIET: PowerStressMessage.Opcode.ValueType # 3 + """Stop powerstress processing - probably by just rebooting the board""" + SCREEN_ON: PowerStressMessage.Opcode.ValueType # 16 + """Turn the screen on""" + SCREEN_OFF: PowerStressMessage.Opcode.ValueType # 17 + """Turn the screen off""" + CPU_IDLE: PowerStressMessage.Opcode.ValueType # 32 + """Let the CPU run but we assume mostly idling for num_seconds""" + CPU_DEEPSLEEP: PowerStressMessage.Opcode.ValueType # 33 + """Force deep sleep for FIXME seconds""" + CPU_FULLON: PowerStressMessage.Opcode.ValueType # 34 + """Spin the CPU as fast as possible for num_seconds""" + LED_ON: PowerStressMessage.Opcode.ValueType # 48 + """Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes)""" + LED_OFF: PowerStressMessage.Opcode.ValueType # 49 + """Force the LED off for num_seconds""" + LORA_OFF: PowerStressMessage.Opcode.ValueType # 64 + """Completely turn off the LORA radio for num_seconds""" + LORA_TX: PowerStressMessage.Opcode.ValueType # 65 + """Send Lora packets for num_seconds""" + LORA_RX: PowerStressMessage.Opcode.ValueType # 66 + """Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel)""" + BT_OFF: PowerStressMessage.Opcode.ValueType # 80 + """Turn off the BT radio for num_seconds""" + BT_ON: PowerStressMessage.Opcode.ValueType # 81 + """Turn on the BT radio for num_seconds""" + WIFI_OFF: PowerStressMessage.Opcode.ValueType # 96 + """Turn off the WIFI radio for num_seconds""" + WIFI_ON: PowerStressMessage.Opcode.ValueType # 97 + """Turn on the WIFI radio for num_seconds""" + GPS_OFF: PowerStressMessage.Opcode.ValueType # 112 + """Turn off the GPS radio for num_seconds""" + GPS_ON: PowerStressMessage.Opcode.ValueType # 113 + """Turn on the GPS radio for num_seconds""" + + CMD_FIELD_NUMBER: builtins.int + NUM_SECONDS_FIELD_NUMBER: builtins.int + cmd: global___PowerStressMessage.Opcode.ValueType + """ + What type of HardwareMessage is this? + """ + num_seconds: builtins.float + def __init__( + self, + *, + cmd: global___PowerStressMessage.Opcode.ValueType = ..., + num_seconds: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["cmd", b"cmd", "num_seconds", b"num_seconds"]) -> None: ... + +global___PowerStressMessage = PowerStressMessage diff --git a/protobufs b/protobufs index a3030d5..c25e0c4 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a3030d5ff187091c9fbbd08dd797cca5085736fe +Subproject commit c25e0c4e0ba99a5e2e94a1ca7313f999bf794fbd From dabb4ea44cde32778946fdbe692bafde97de990e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 28 Jun 2024 09:40:33 -0700 Subject: [PATCH 080/248] PowerStress client approximately works --- meshtastic/__main__.py | 8 +++---- meshtastic/powermon/stress.py | 4 ++-- meshtastic/slog/slog.py | 40 +++++++++++++++++++++-------------- protobufs | 2 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index f479009..bc93c27 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -852,14 +852,14 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) - if args.slog_out: + if args.slog_out or args.power_stress: # Setup loggers global meter LogSet(interface, args.slog_out if args.slog_out != 'default' else None, meter) - if args.power_stress: - stress = PowerStress(interface) - stress.run() + if args.power_stress: + stress = PowerStress(interface) + stress.run() if args.listen: closeNow = False diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py index b847e12..0ab8d7d 100644 --- a/meshtastic/powermon/stress.py +++ b/meshtastic/powermon/stress.py @@ -47,7 +47,7 @@ class PowerStressClient: self.node_id, portnums_pb2.POWERSTRESS_APP, wantAck=True, - wantResponse=False, + wantResponse=True, onResponse=onResponse, onResponseAckPermitted=True ) @@ -64,7 +64,7 @@ class PowerStress: # Send the power stress command gotAck = False - def onResponse(packet, interface): + def onResponse(packet: dict): # pylint: disable=unused-argument nonlocal gotAck gotAck = True diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 7f99d38..e7c8efc 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -1,11 +1,11 @@ """code logging power consumption of meshtastic devices.""" import atexit +import io import logging import os import re import threading -import io import time from dataclasses import dataclass from datetime import datetime @@ -100,10 +100,17 @@ class StructuredLogger: """ self.client = client self.writer = FeatherWriter(f"{dir_path}/slog") - self.raw_file: Optional[io.TextIOWrapper] = open( # pylint: disable=consider-using-with + self.raw_file: Optional[ + io.TextIOWrapper + ] = open( # pylint: disable=consider-using-with f"{dir_path}/raw.txt", "w", encoding="utf8" ) - self.listener = pub.subscribe(self._onLogMessage, TOPIC_MESHTASTIC_LOG_LINE) + + # We need a closure here because the subscription API is very strict about exact arg matching + def listen_glue(line, interface): # pylint: disable=unused-argument + self._onLogMessage(line) + + self.listener = pub.subscribe(listen_glue, TOPIC_MESHTASTIC_LOG_LINE) def close(self) -> None: """Stop logging.""" @@ -113,9 +120,7 @@ class StructuredLogger: self.raw_file = None # mark that we are shutting down f.close() # Close the raw.txt file - def _onLogMessage( - self, line: str, interface: MeshInterface # pylint: disable=unused-argument - ) -> None: + def _onLogMessage(self, line: str) -> None: """Handle log messages. line (str): the line of log output @@ -126,17 +131,20 @@ class StructuredLogger: args = m.group(2) args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match logging.debug(f"SLog {src}, reason: {args}") - d = log_defs.get(src) - if d: - r = d.format.parse(args) # get the values with the correct types - if r: - di = r.named - di["time"] = datetime.now() - self.writer.add_row(di) - else: - logging.warning(f"Failed to parse slog {line} with {d.format}") + if(src != "PM"): + logging.warning(f"Not yet handling structured log {src} (FIXME)") else: - logging.warning(f"Unknown Structured Log: {line}") + d = log_defs.get(src) + if d: + r = d.format.parse(args) # get the values with the correct types + if r: + di = r.named + di["time"] = datetime.now() + self.writer.add_row(di) + else: + logging.warning(f"Failed to parse slog {line} with {d.format}") + else: + logging.warning(f"Unknown Structured Log: {line}") if self.raw_file: self.raw_file.write(line + "\n") # Write the raw log diff --git a/protobufs b/protobufs index c25e0c4..9d747b6 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit c25e0c4e0ba99a5e2e94a1ca7313f999bf794fbd +Subproject commit 9d747b6cf08e2762fdf9530173a7ff825b9daa90 From 542f99b28f8a6406b44f348c67e5849f63b6a987 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 28 Jun 2024 09:41:17 -0700 Subject: [PATCH 081/248] handle the new LogRecord protobufs (backwards/forwards compatible) with old firmware --- meshtastic/mesh_interface.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index af76714..38eca07 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -150,6 +150,11 @@ class MeshInterface: # pylint: disable=R0902 """Handle a line of log output from the device.""" pub.sendMessage("meshtastic.log.line", line=line, interface=self) + def _handleLogRecord(self, record: mesh_pb2.LogRecord) -> None: + """Handle a log record which was received encapsulated in a protobuf.""" + # For now we just try to format the line as if it had come in over the serial port + self._handleLogLine(record.message) + def showInfo(self, file=sys.stdout) -> str: # pylint: disable=W0613 """Show human readable summary about this object""" owner = f"Owner: {self.getLongName()} ({self.getShortName()})" @@ -927,7 +932,8 @@ class MeshInterface: # pylint: disable=R0902 self._handleChannel(fromRadio.channel) elif fromRadio.HasField("packet"): self._handlePacketFromRadio(fromRadio.packet) - + elif fromRadio.HasField("log_record"): + self._handleLogRecord(fromRadio.log_record) elif fromRadio.HasField("queueStatus"): self._handleQueueStatusFromRadio(fromRadio.queueStatus) From 897adfb8c2786bfc846762282b78547a99dd6b79 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 29 Jun 2024 09:41:06 -0500 Subject: [PATCH 082/248] Adds support for ble logging characteristic --- meshtastic/ble_interface.py | 18 ++++++++++++++++++ poetry.lock | 13 ++++++++++++- pyproject.toml | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 1c12758..d1c9fd5 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -6,6 +6,7 @@ import struct import asyncio from threading import Thread, Event from typing import Optional +from print_color import print from bleak import BleakScanner, BleakClient @@ -16,6 +17,8 @@ SERVICE_UUID = "6ba1b218-15a8-461f-9fa8-5dcae273eafd" TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7" FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002" FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453" +LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" + class BLEInterface(MeshInterface): @@ -70,6 +73,7 @@ class BLEInterface(MeshInterface): logging.debug("Register FROMNUM notify callback") self.client.start_notify(FROMNUM_UUID, self.from_num_handler) + self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) async def from_num_handler(self, _, b): # pylint: disable=C0116 @@ -77,6 +81,20 @@ class BLEInterface(MeshInterface): logging.debug(f"FROMNUM notify: {from_num}") self.should_read = True + async def log_radio_handler(self, _, b): # pylint: disable=C0116 + log_radio = b.decode('utf-8').replace('\n', '') + if log_radio.startswith("DEBUG"): + print(log_radio, color="cyan", end=None) + elif log_radio.startswith("INFO"): + print(log_radio, color="white", end=None) + elif log_radio.startswith("WARN"): + print(log_radio, color="yellow", end=None) + elif log_radio.startswith("ERROR"): + print(log_radio, color="red", end=None) + else: + print(log_radio, end=None) + + self.should_read = False def scan(self): "Scan for available BLE devices" diff --git a/poetry.lock b/poetry.lock index dd7228f..915c63f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -762,6 +762,17 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "print-color" +version = "0.4.6" +description = "A simple package to print in color to the terminal" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "print_color-0.4.6-py3-none-any.whl", hash = "sha256:494bd1cdb84daf481f0e63bd22b3c32f7d52827d8f5d9138a96bb01ca8ba9299"}, + {file = "print_color-0.4.6.tar.gz", hash = "sha256:d3aafc1666c8d31a85fffa6ee8e4f269f5d5e338d685b4e6179915c71867c585"}, +] + [[package]] name = "protobuf" version = "5.27.1" @@ -1552,4 +1563,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.13" -content-hash = "8548a8b432a3f62db158f5b35254b05b2599aafe75ef12100471937fd4603e3c" +content-hash = "8e82c70af84ffd1525ece9c446bf06c9a1a1235cdf3bb6c563413daf389de353" diff --git a/pyproject.toml b/pyproject.toml index dc1f2ae..730ca20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" packaging = "^24.0" +print-color = "^0.4.6" [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" From 821d3e95f15e378e95619f4f965cdb5886927b21 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 08:40:16 -0700 Subject: [PATCH 083/248] remvoe unneeded paren --- meshtastic/slog/slog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index e7c8efc..9c6ae6d 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -131,7 +131,7 @@ class StructuredLogger: args = m.group(2) args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match logging.debug(f"SLog {src}, reason: {args}") - if(src != "PM"): + if src != "PM": logging.warning(f"Not yet handling structured log {src} (FIXME)") else: d = log_defs.get(src) From 6df89f54a79f8a012b8d1040e6339147c9ef7caf Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 09:10:20 -0700 Subject: [PATCH 084/248] fix BLE scan with latest Bleak --- .vscode/launch.json | 8 +++ meshtastic/__main__.py | 8 +-- meshtastic/ble_interface.py | 117 +++++++++++++++++++----------------- 3 files changed, 73 insertions(+), 60 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 911eb4d..c1bb9ef 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,14 @@ "module": "meshtastic", "justMyCode": false, "args": ["--debug", "--ble", "24:62:AB:DD:DF:3A"] + }, + { + "name": "meshtastic BLE scan", + "type": "python", + "request": "launch", + "module": "meshtastic", + "justMyCode": false, + "args": ["--debug", "--ble-scan"] }, { "name": "meshtastic admin", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index e6c2362..8bebf41 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1041,12 +1041,8 @@ def common(): subscribe() if args.ble_scan: logging.debug("BLE scan starting") - client = BLEInterface(None, debugOut=logfile, noProto=args.noproto) - try: - for x in client.scan(): - print(f"Found: name='{x[1].local_name}' address='{x[0].address}'") - finally: - client.close() + for x in BLEInterface.scan(): + print(f"Found: name='{x.name}' address='{x.address}'") meshtastic.util.our_exit("BLE scan finished", 0) return elif args.ble: diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 0624db6..9067878 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -1,13 +1,13 @@ """Bluetooth interface """ -import logging -import time -import struct import asyncio -from threading import Thread, Event +import logging +import struct +import time +from threading import Event, Thread from typing import Optional -from bleak import BleakScanner, BleakClient, BLEDevice +from bleak import BleakClient, BleakScanner, BLEDevice from meshtastic.mesh_interface import MeshInterface from meshtastic.util import our_exit @@ -20,25 +20,32 @@ FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453" class BLEInterface(MeshInterface): """MeshInterface using BLE to connect to devices""" + class BLEError(Exception): """An exception class for BLE errors""" + def __init__(self, message): self.message = message super().__init__(self.message) - class BLEState(): # pylint: disable=C0115 + class BLEState: # pylint: disable=C0115 THREADS = False BLE = False MESH = False - - def __init__(self, address: Optional[str], noProto: bool = False, debugOut = None, noNodes: bool = False): + def __init__( + self, + address: Optional[str], + noProto: bool = False, + debugOut=None, + noNodes: bool = False, + ): self.state = BLEInterface.BLEState() self.should_read = False logging.debug("Threads starting") - self._receiveThread = Thread(target = self._receiveFromRadioImpl) + self._receiveThread = Thread(target=self._receiveFromRadioImpl) self._receiveThread_started = Event() self._receiveThread_stopped = Event() self._receiveThread.start() @@ -56,10 +63,12 @@ class BLEInterface(MeshInterface): raise e logging.debug("Mesh init starting") - MeshInterface.__init__(self, debugOut = debugOut, noProto = noProto, noNodes = noNodes) + MeshInterface.__init__( + self, debugOut=debugOut, noProto=noProto, noNodes=noNodes + ) self._startConfig() if not self.noProto: - self._waitConnected(timeout = 60.0) + self._waitConnected(timeout=60.0) self.waitForConfig() self.state.MESH = True logging.debug("Mesh init finished") @@ -67,53 +76,55 @@ class BLEInterface(MeshInterface): logging.debug("Register FROMNUM notify callback") self.client.start_notify(FROMNUM_UUID, self.from_num_handler) - - async def from_num_handler(self, _, b): # pylint: disable=C0116 - from_num = struct.unpack(' list[BLEDevice]: + @staticmethod + def scan() -> list[BLEDevice]: """Scan for available BLE devices.""" with BLEClient() as client: - response = client.discover( - return_adv = True, - service_uuids=[SERVICE_UUID] - ) + response = client.discover(return_adv=True, service_uuids=[SERVICE_UUID]) devices = response.values() # bleak sometimes returns devices we didn't ask for, so filter the response # to only return true meshtastic devices # d[0] is the device. d[1] is the advertisement data - devices = list(filter(lambda d: SERVICE_UUID in d[1].service_uuids, devices)) + devices = list( + filter(lambda d: SERVICE_UUID in d[1].service_uuids, devices) + ) return list(map(lambda d: d[0], devices)) - def find_device(self, address: Optional[str]) -> BLEDevice: - """Find a device by address""" - addressed_devices = self.scan() + """Find a device by address.""" + addressed_devices = BLEInterface.scan() if address: - addressed_devices = list(filter(lambda x: address == x.name or address == x.address, addressed_devices)) + addressed_devices = list( + filter( + lambda x: address == x.name or address == x.address, + addressed_devices, + ) + ) if len(addressed_devices) == 0: - raise BLEInterface.BLEError(f"No Meshtastic BLE peripheral with identifier or address '{address}' found. Try --ble-scan to find it.") + raise BLEInterface.BLEError( + f"No Meshtastic BLE peripheral with identifier or address '{address}' found. Try --ble-scan to find it." + ) if len(addressed_devices) > 1: - raise BLEInterface.BLEError(f"More than one Meshtastic BLE peripheral with identifier or address '{address}' found.") + raise BLEInterface.BLEError( + f"More than one Meshtastic BLE peripheral with identifier or address '{address}' found." + ) return addressed_devices[0] - def _sanitize_address(address): # pylint: disable=E0213 - "Standardize BLE address by removing extraneous characters and lowercasing" - return address \ - .replace("-", "") \ - .replace("_", "") \ - .replace(":", "") \ - .lower() + def _sanitize_address(address): # pylint: disable=E0213 + "Standardize BLE address by removing extraneous characters and lowercasing." + return address.replace("-", "").replace("_", "").replace(":", "").lower() def connect(self, address: Optional[str] = None): - "Connect to a device by address" + "Connect to a device by address." # Bleak docs recommend always doing a scan before connecting (even if we know addr) device = self.find_device(address) @@ -121,7 +132,6 @@ class BLEInterface(MeshInterface): client.connect() return client - def _receiveFromRadioImpl(self): self._receiveThread_started.set() while self._receiveThread_started.is_set(): @@ -146,12 +156,11 @@ class BLEInterface(MeshInterface): b = toRadio.SerializeToString() if b: logging.debug(f"TORADIO write: {b.hex()}") - self.client.write_gatt_char(TORADIO_UUID, b, response = True) + self.client.write_gatt_char(TORADIO_UUID, b, response=True) # Allow to propagate and then make sure we read time.sleep(0.1) self.should_read = True - def close(self): if self.state.MESH: MeshInterface.close(self) @@ -165,10 +174,11 @@ class BLEInterface(MeshInterface): self.client.close() -class BLEClient(): +class BLEClient: """Client for managing connection to a BLE device""" - def __init__(self, address = None, **kwargs): - self._eventThread = Thread(target = self._run_event_loop) + + def __init__(self, address=None, **kwargs): + self._eventThread = Thread(target=self._run_event_loop) self._eventThread_started = Event() self._eventThread_stopped = Event() self._eventThread.start() @@ -180,47 +190,46 @@ class BLEClient(): self.bleak_client = BleakClient(address, **kwargs) - - def discover(self, **kwargs): # pylint: disable=C0116 + def discover(self, **kwargs): # pylint: disable=C0116 return self.async_await(BleakScanner.discover(**kwargs)) - def pair(self, **kwargs): # pylint: disable=C0116 + def pair(self, **kwargs): # pylint: disable=C0116 return self.async_await(self.bleak_client.pair(**kwargs)) - def connect(self, **kwargs): # pylint: disable=C0116 + def connect(self, **kwargs): # pylint: disable=C0116 return self.async_await(self.bleak_client.connect(**kwargs)) - def disconnect(self, **kwargs): # pylint: disable=C0116 + def disconnect(self, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.disconnect(**kwargs)) - def read_gatt_char(self, *args, **kwargs): # pylint: disable=C0116 + def read_gatt_char(self, *args, **kwargs): # pylint: disable=C0116 return self.async_await(self.bleak_client.read_gatt_char(*args, **kwargs)) - def write_gatt_char(self, *args, **kwargs): # pylint: disable=C0116 + def write_gatt_char(self, *args, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.write_gatt_char(*args, **kwargs)) - def start_notify(self, *args, **kwargs): # pylint: disable=C0116 + def start_notify(self, *args, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.start_notify(*args, **kwargs)) - def close(self): # pylint: disable=C0116 + def close(self): # pylint: disable=C0116 self.async_run(self._stop_event_loop()) self._eventThread_stopped.wait(5) def __enter__(self): return self - + def __exit__(self, _type, _value, _traceback): self.close() - def async_await(self, coro, timeout = None): # pylint: disable=C0116 + def async_await(self, coro, timeout=None): # pylint: disable=C0116 return self.async_run(coro).result(timeout) - def async_run(self, coro): # pylint: disable=C0116 + def async_run(self, coro): # pylint: disable=C0116 return asyncio.run_coroutine_threadsafe(coro, self._eventLoop) def _run_event_loop(self): # I don't know if the event loop can be initialized in __init__ so silencing pylint - self._eventLoop = asyncio.new_event_loop() # pylint: disable=W0201 + self._eventLoop = asyncio.new_event_loop() # pylint: disable=W0201 self._eventThread_started.set() try: self._eventLoop.run_forever() From adbfb328b201bea5da8777007568a7583d9e9016 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 09:29:29 -0700 Subject: [PATCH 085/248] threads should aways be named (for debugability) --- meshtastic/ble_interface.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 9067878..9b9b602 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -19,10 +19,10 @@ FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453" class BLEInterface(MeshInterface): - """MeshInterface using BLE to connect to devices""" + """MeshInterface using BLE to connect to devices.""" class BLEError(Exception): - """An exception class for BLE errors""" + """An exception class for BLE errors.""" def __init__(self, message): self.message = message @@ -54,7 +54,7 @@ class BLEInterface(MeshInterface): logging.debug("Threads running") try: - logging.debug(f"BLE connecting to: {address}") + logging.debug(f"BLE connecting to: {address if address else 'any'}") self.client = self.connect(address) self.state.BLE = True logging.debug("BLE connected") @@ -178,7 +178,7 @@ class BLEClient: """Client for managing connection to a BLE device""" def __init__(self, address=None, **kwargs): - self._eventThread = Thread(target=self._run_event_loop) + self._eventThread = Thread(target=self._run_event_loop, name="BLEClient") self._eventThread_started = Event() self._eventThread_stopped = Event() self._eventThread.start() From dc50a60b016552a7e5513a6096ec762925b52d1c Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 09:35:42 -0700 Subject: [PATCH 086/248] BLE debugging --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c1bb9ef..ff2f013 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--debug", "--ble", "24:62:AB:DD:DF:3A"] + "args": ["--debug", "--ble", "--ble-dest", "Meshtastic_9f6e"] }, { "name": "meshtastic BLE scan", From 9f015f499ae2692d54ea0dc7295629997a6fc364 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 10:18:37 -0700 Subject: [PATCH 087/248] wow Bleak now seems pretty buggy to me (compared to 2 yrs ago) --- meshtastic/ble_interface.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index d1ca6ca..fbe77a9 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -26,10 +26,7 @@ class BLEInterface(MeshInterface): class BLEError(Exception): """An exception class for BLE errors.""" - - def __init__(self, message): - self.message = message - super().__init__(self.message) + pass class BLEState: # pylint: disable=C0115 THREADS = False @@ -118,15 +115,21 @@ class BLEInterface(MeshInterface): def find_device(self, address: Optional[str]) -> BLEDevice: """Find a device by address.""" - addressed_devices = BLEInterface.scan() - if address: - addressed_devices = list( - filter( - lambda x: address == x.name or address == x.address, - addressed_devices, + # Bleak scan is buggy (only on linux?) Try a few times + for _ in range(5): + addressed_devices = BLEInterface.scan() + + if address: + addressed_devices = list( + filter( + lambda x: address == x.name or address == x.address, + addressed_devices, + ) ) - ) + # We finally found something? + if len(addressed_devices) > 0: + break if len(addressed_devices) == 0: raise BLEInterface.BLEError( @@ -158,7 +161,10 @@ class BLEInterface(MeshInterface): self.should_read = False retries = 0 while True: - b = bytes(self.client.read_gatt_char(FROMRADIO_UUID)) + try: + b = bytes(self.client.read_gatt_char(FROMRADIO_UUID)) + except Exception as e: + raise BLEInterface.BLEError("Error reading BLE") from e if not b: if retries < 5: time.sleep(0.1) @@ -175,7 +181,10 @@ class BLEInterface(MeshInterface): b = toRadio.SerializeToString() if b: logging.debug(f"TORADIO write: {b.hex()}") - self.client.write_gatt_char(TORADIO_UUID, b, response=True) + try: + self.client.write_gatt_char(TORADIO_UUID, b, response=False) + except Exception as e: + raise BLEInterface.BLEError("Error writing BLE") from e # Allow to propagate and then make sure we read time.sleep(0.1) self.should_read = True From 898018ebf35df827d600a05ab5bb12ee098cdaa7 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 13:52:46 -0700 Subject: [PATCH 088/248] yay Bleak works again on Linux! --- .vscode/launch.json | 2 +- meshtastic/ble_interface.py | 43 ++++----- poetry.lock | 187 +++++++++++++++++------------------- 3 files changed, 112 insertions(+), 120 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ff2f013..6c9c892 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--debug", "--ble", "--ble-dest", "Meshtastic_9f6e"] + "args": ["--ble", "--ble-dest", "Meshtastic_9f6e"] }, { "name": "meshtastic BLE scan", diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index fbe77a9..96293d0 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -45,7 +45,7 @@ class BLEInterface(MeshInterface): self.should_read = False logging.debug("Threads starting") - self._receiveThread = Thread(target=self._receiveFromRadioImpl) + self._receiveThread = Thread(target=self._receiveFromRadioImpl, name="BLEReceive", daemon=True) self._receiveThread_started = Event() self._receiveThread_stopped = Event() self._receiveThread.start() @@ -62,6 +62,8 @@ class BLEInterface(MeshInterface): self.close() raise e + self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) + logging.debug("Mesh init starting") MeshInterface.__init__( self, debugOut=debugOut, noProto=noProto, noNodes=noNodes @@ -75,9 +77,10 @@ class BLEInterface(MeshInterface): logging.debug("Register FROMNUM notify callback") self.client.start_notify(FROMNUM_UUID, self.from_num_handler) - self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) - async def from_num_handler(self, _, b): # pylint: disable=C0116 + def from_num_handler(self, _, b): # 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(" list[BLEDevice]: """Scan for available BLE devices.""" with BLEClient() as client: - response = client.discover(return_adv=True, service_uuids=[SERVICE_UUID]) + logging.info("Scanning for BLE devices (takes 10 seconds)...") + response = client.discover(timeout=10, return_adv=True, service_uuids=[SERVICE_UUID]) devices = response.values() @@ -116,20 +118,15 @@ class BLEInterface(MeshInterface): def find_device(self, address: Optional[str]) -> BLEDevice: """Find a device by address.""" - # Bleak scan is buggy (only on linux?) Try a few times - for _ in range(5): - addressed_devices = BLEInterface.scan() + addressed_devices = BLEInterface.scan() - if address: - addressed_devices = list( - filter( - lambda x: address == x.name or address == x.address, - addressed_devices, - ) + if address: + addressed_devices = list( + filter( + lambda x: address == x.name or address == x.address, + addressed_devices, ) - # We finally found something? - if len(addressed_devices) > 0: - break + ) if len(addressed_devices) == 0: raise BLEInterface.BLEError( @@ -152,6 +149,7 @@ class BLEInterface(MeshInterface): device = self.find_device(address) client = BLEClient(device.address) client.connect() + client.discover() return client def _receiveFromRadioImpl(self): @@ -182,11 +180,12 @@ class BLEInterface(MeshInterface): if b: logging.debug(f"TORADIO write: {b.hex()}") try: - self.client.write_gatt_char(TORADIO_UUID, b, response=False) + self.client.write_gatt_char(TORADIO_UUID, b, response=True) # FIXME: or False? + # search Bleak src for org.bluez.Error.InProgress except Exception as e: - raise BLEInterface.BLEError("Error writing BLE") from e + raise BLEInterface.BLEError("Error writing BLE (are you in the 'bluetooth' user group? did you enter the pairing PIN on your computer?)") from e # Allow to propagate and then make sure we read - time.sleep(0.1) + time.sleep(0.01) self.should_read = True def close(self): @@ -206,7 +205,7 @@ class BLEClient: """Client for managing connection to a BLE device""" def __init__(self, address=None, **kwargs): - self._eventThread = Thread(target=self._run_event_loop, name="BLEClient") + self._eventThread = Thread(target=self._run_event_loop, name="BLEClient", daemon=True) self._eventThread_started = Event() self._eventThread_stopped = Event() self._eventThread.start() diff --git a/poetry.lock b/poetry.lock index 915c63f..3331326 100644 --- a/poetry.lock +++ b/poetry.lock @@ -57,13 +57,13 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "autopep8" -version = "2.3.0" +version = "2.3.1" description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" optional = false python-versions = ">=3.8" files = [ - {file = "autopep8-2.3.0-py2.py3-none-any.whl", hash = "sha256:b716efa70cbafbf4a2c9c5ec1cabfa037a68f9e30b04c74ffa5864dd49b8f7d2"}, - {file = "autopep8-2.3.0.tar.gz", hash = "sha256:5cfe45eb3bef8662f6a3c7e28b7c0310c7310d340074b7f0f28f9810b44b7ef4"}, + {file = "autopep8-2.3.1-py2.py3-none-any.whl", hash = "sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d"}, + {file = "autopep8-2.3.1.tar.gz", hash = "sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda"}, ] [package.dependencies] @@ -307,45 +307,39 @@ toml = ["tomli"] [[package]] name = "dbus-fast" -version = "2.21.3" +version = "2.22.1" description = "A faster version of dbus-next" optional = false -python-versions = "<4.0,>=3.7" +python-versions = "<4.0,>=3.8" files = [ - {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:828f2a337eac4c3b24b43ab4edc8d8bc656f558a4f07aa2b173e007ce093bd49"}, - {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b379ed7ef0d174480e41a5f1dde3392d974e618bb91e5fbfa06396c24d3c80fc"}, - {file = "dbus_fast-2.21.3-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:990d60e9796fa142e16af331e53d91aaa94dfbcf37b474c1d6caf61310fcc5ee"}, - {file = "dbus_fast-2.21.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9d0bbfa7cdb440f13d58e13625344b918b70ff0ccddc20ddd9c0ebf3e5a765dd"}, - {file = "dbus_fast-2.21.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0d4f459ba4fa394e3ba22a7421055878953aa92efd01e3a1d5216519c6b1586c"}, - {file = "dbus_fast-2.21.3-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:61d20cecc3efdc0e75bb7d5f4ae18929559003644b32945bfaa93b7e06cd94b6"}, - {file = "dbus_fast-2.21.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d53f5b24c732af5ae9c7e88fc9ba687ce2a785c63dcea3b9c984619f1bdcf71a"}, - {file = "dbus_fast-2.21.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b5ef802b2b7e5dbebdfa338a0278e5212a6073c26764c75f3e373e2a9b01797c"}, - {file = "dbus_fast-2.21.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:251d46d0d7cbed0d9b9eac2f91f6669893db9b87e19defb99f9a85579c2f786a"}, - {file = "dbus_fast-2.21.3-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:0665d8cb179f0b8fff23e63592c1f454fdaa4ae44a4263a7a7b7df8d834b3f71"}, - {file = "dbus_fast-2.21.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ca29609a31f816c315844ed41b81247e3114261d26e5ee1dcc85bf5c046a36"}, - {file = "dbus_fast-2.21.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b520792549e8b2b1e4c8777492783ba81065bd02e16e4390e2b299bf33f1feea"}, - {file = "dbus_fast-2.21.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f44d2ea35daefac7ad1ede65695fde18526fb38f9ec0aadf108f629bb6c87293"}, - {file = "dbus_fast-2.21.3-cp37-cp37m-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:50aa62f63de3e591d739b4925816b84f4169e9086701a2722a5e7a1f6f273bc0"}, - {file = "dbus_fast-2.21.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8fad077a989b002602aa192cfa95b89b3e40c5fa6da7740f42a87488bdbed6f"}, - {file = "dbus_fast-2.21.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87e8db4ea5023024a638826321039497dcbc7e70583bd33743eac2d8e69ca4fb"}, - {file = "dbus_fast-2.21.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0c342d8b33079c550ea575344d53807f6ae6464b1a5f6f9e0523fae979198872"}, - {file = "dbus_fast-2.21.3-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:41d6f81a5226e90f1bde95ce90a63430f58aea0c300f034b4055a7bfae187031"}, - {file = "dbus_fast-2.21.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d76b512cc8db4ebdfb7879d7cae42ee0adc362671bc0a4f55df5f4ebe547602d"}, - {file = "dbus_fast-2.21.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9fdbe2b22668f4021e909e65fa6a25bca1ab08294a35c600af95ba06a2f2d101"}, - {file = "dbus_fast-2.21.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:638c4b64159f8a3567e38705246bd1a2625d8c9adbb7ffa23a6a2ec2dfd40db0"}, - {file = "dbus_fast-2.21.3-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:dadc4bdcbe808f0d1750f951b3b4211763f280116714cb9749ebae2262bdc49c"}, - {file = "dbus_fast-2.21.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83e0a28e04218493ebd66c1f2a5290203ffff924ec01b37c5128ba1fa9731255"}, - {file = "dbus_fast-2.21.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:846733011edad8c0125f2b1148783c8d2ae162419707bb7e2bf08a26040939d8"}, - {file = "dbus_fast-2.21.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:07213240465c3c7306705ad512c983ada45ef222d2eecf3d7ab19f397b02de0d"}, - {file = "dbus_fast-2.21.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8bfea9007a654adc5c16d43d124fded0c788fdb2a6e2c470fcfd7d0076bda87e"}, - {file = "dbus_fast-2.21.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5b202ffd4314c82f68b2431d928d596c45def381c018832003045f19ed857a"}, - {file = "dbus_fast-2.21.3-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:19091565dd9b5db9b3fa82459361c459387c01b11a656f36cab6a73284300c8c"}, - {file = "dbus_fast-2.21.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa74eb299ec88319a6a46c9b59aeebf9782378d9724913bcb3fb746a3222f70a"}, - {file = "dbus_fast-2.21.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:2bb2a659f31e1af87a3c4e41af3af69cb5a2bb4a335b35d8d6e80b43e8aed8e9"}, - {file = "dbus_fast-2.21.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56bf648a329257b127ee05667451e929c50ada7117737d14341a5399ca7860e1"}, - {file = "dbus_fast-2.21.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:4bb07da46377b7affe648ce34ac42fb3409e87b40b55d64f0fd23512e583ce46"}, - {file = "dbus_fast-2.21.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b07d22e167b0af834344bd1c8619b702b823d8989d6884fc9719c6e871c413f5"}, - {file = "dbus_fast-2.21.3.tar.gz", hash = "sha256:8d0f0f61d007c1316ce79cde35ed52c0ce8ce229fd0f0bf8c9af2013ab4516a7"}, + {file = "dbus_fast-2.22.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f19c08fc0ab5f0e209e008f4646bb0624eacb96fb54367ea36e450aacfe289f"}, + {file = "dbus_fast-2.22.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:714c5bca7d1ae20557a5857fdb3022ff0a3f5ef2e14379eae0403940882a4d72"}, + {file = "dbus_fast-2.22.1-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:ac004b0f6a7f7b58ae7488f12463df68199546a8d71085379b5eed17ae012905"}, + {file = "dbus_fast-2.22.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a54533ee4b30a2c062078c02d10c5a258fc10eac51a0b85cfdd7f690f1d6285f"}, + {file = "dbus_fast-2.22.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cadf90548aaf336820e0b7037b0f0f46b9836ac0f2c6af0f494b00fe6bc23929"}, + {file = "dbus_fast-2.22.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e213b0252f97d6a9ceb97cd2d84ddac0d998b8dd15bdca051def181a666b6a"}, + {file = "dbus_fast-2.22.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6497859da721041dbf7615aab1cae666e5c0a169fca80032ab2fd8b03f7730f5"}, + {file = "dbus_fast-2.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a3ba17d91a32b53f8e16b40e7f948260847f3e8fbbbf83872dafe44b38a1ae42"}, + {file = "dbus_fast-2.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2b7f32e765051817d58e3242697b47cfe5def086181ad1087c9bc70e2db48004"}, + {file = "dbus_fast-2.22.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:beebe8cbd0cd90d24b757c4aad617fcfa77f2e654287bc80b11c0e4964891c22"}, + {file = "dbus_fast-2.22.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72ebd07ac873906f1001cb6eb75e864e30cb6cdcce17afe79939987b0a28b5"}, + {file = "dbus_fast-2.22.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c73e3b59de2b6e7447b1c3d26ccd307838d05c6a85bcc9eac7bc990bb843cc92"}, + {file = "dbus_fast-2.22.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dcb333f56ebb0de5cf3aa8affb9c492bd821e252d704dcce444a379c0513c6be"}, + {file = "dbus_fast-2.22.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2980b92493698f80910b3521d685ce230f94d93deac0bcf33f2082ce551b8ac5"}, + {file = "dbus_fast-2.22.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d88f7f1d4124feb4418f5d9efe359661e2f38e89f6c31539d998e3769f7f7b3"}, + {file = "dbus_fast-2.22.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:bf198217013b068fe610b1d5ce7ce53e15b993625331d2c83f53be5744c0be40"}, + {file = "dbus_fast-2.22.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f90017ba2c95dba4c1e417850d3c735d5eb464cbe0ebfb5d49cc0e95e7d916d2"}, + {file = "dbus_fast-2.22.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98e6d2cd04da08a9d21be68faa4d23123a2f4cb5cef3406cc1a2ef900507b1c0"}, + {file = "dbus_fast-2.22.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2735f9cc9e6692b0bb114c48580709af824a16ea791922f628c265aa05f183a"}, + {file = "dbus_fast-2.22.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b709a9eaaae542d0d883c5a2f147c0cbe7ef29262ec0bf90f5a5945e76786c39"}, + {file = "dbus_fast-2.22.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7e7924d5042de42dcdc6be942d2f6cf1f187cf7a4ae2902b68431ea856ef654c"}, + {file = "dbus_fast-2.22.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e15b15c0bdef24f86a5940539ba68d0920d58b96cca8543fbda9189cb144fb13"}, + {file = "dbus_fast-2.22.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f70821ac238e3fa0f5a6ae4e99054d57261743f5d5516e43226f2bec0065a3d"}, + {file = "dbus_fast-2.22.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e56f6f0976aa953a2a5c71817e9ceecace6dd6a2a23dc64622025701005bf15"}, + {file = "dbus_fast-2.22.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6f894fe9b60374dc20c43bdf7a5b4a81e2db963433815a9d6ceaaeb51cba801"}, + {file = "dbus_fast-2.22.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0934118cc2e4f777d785df923b139f253ba3019469ec1f90eb8a5e4c12fff0ce"}, + {file = "dbus_fast-2.22.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994931d9bc57166a9e16ae71cb93133fa87f35d57125d741a92a1f4e56cade28"}, + {file = "dbus_fast-2.22.1.tar.gz", hash = "sha256:aa75dfb5bc7ba42f53391ae503ca5a21bd133e74ebb09965013ba23bdffc9a0e"}, ] [[package]] @@ -390,13 +384,13 @@ test = ["pytest (>=6)"] [[package]] name = "hypothesis" -version = "6.103.2" +version = "6.104.2" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.103.2-py3-none-any.whl", hash = "sha256:629b7cdeca8c225933739f99879caba21949000d2c919c8b4585e01048b3bc73"}, - {file = "hypothesis-6.103.2.tar.gz", hash = "sha256:83504e31e90a0d7d6e8eb93e51525dc1a48d79c932a50ad6035e29f8295328cd"}, + {file = "hypothesis-6.104.2-py3-none-any.whl", hash = "sha256:8b52b7e2462e552c75b819495d5cb6251a2b840accc79cf2ce52588004c915d9"}, + {file = "hypothesis-6.104.2.tar.gz", hash = "sha256:6f2a1489bc8fe1c87ffd202707319b66ec46b2bc11faf6e0161e957b8b9b1eab"}, ] [package.dependencies] @@ -405,10 +399,10 @@ exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.54)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.55)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] -crosshair = ["crosshair-tool (>=0.0.54)", "hypothesis-crosshair (>=0.0.4)"] +crosshair = ["crosshair-tool (>=0.0.55)", "hypothesis-crosshair (>=0.0.4)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] @@ -434,13 +428,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.0" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, - {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] @@ -609,38 +603,38 @@ files = [ [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] @@ -775,22 +769,22 @@ files = [ [[package]] name = "protobuf" -version = "5.27.1" +version = "5.27.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.27.1-cp310-abi3-win32.whl", hash = "sha256:3adc15ec0ff35c5b2d0992f9345b04a540c1e73bfee3ff1643db43cc1d734333"}, - {file = "protobuf-5.27.1-cp310-abi3-win_amd64.whl", hash = "sha256:25236b69ab4ce1bec413fd4b68a15ef8141794427e0b4dc173e9d5d9dffc3bcd"}, - {file = "protobuf-5.27.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e38fc29d7df32e01a41cf118b5a968b1efd46b9c41ff515234e794011c78b17"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:917ed03c3eb8a2d51c3496359f5b53b4e4b7e40edfbdd3d3f34336e0eef6825a"}, - {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:ee52874a9e69a30271649be88ecbe69d374232e8fd0b4e4b0aaaa87f429f1631"}, - {file = "protobuf-5.27.1-cp38-cp38-win32.whl", hash = "sha256:7a97b9c5aed86b9ca289eb5148df6c208ab5bb6906930590961e08f097258107"}, - {file = "protobuf-5.27.1-cp38-cp38-win_amd64.whl", hash = "sha256:f6abd0f69968792da7460d3c2cfa7d94fd74e1c21df321eb6345b963f9ec3d8d"}, - {file = "protobuf-5.27.1-cp39-cp39-win32.whl", hash = "sha256:dfddb7537f789002cc4eb00752c92e67885badcc7005566f2c5de9d969d3282d"}, - {file = "protobuf-5.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:39309898b912ca6febb0084ea912e976482834f401be35840a008da12d189340"}, - {file = "protobuf-5.27.1-py3-none-any.whl", hash = "sha256:4ac7249a1530a2ed50e24201d6630125ced04b30619262f06224616e0030b6cf"}, - {file = "protobuf-5.27.1.tar.gz", hash = "sha256:df5e5b8e39b7d1c25b186ffdf9f44f40f810bbcc9d2b71d9d3156fee5a9adf15"}, + {file = "protobuf-5.27.2-cp310-abi3-win32.whl", hash = "sha256:354d84fac2b0d76062e9b3221f4abbbacdfd2a4d8af36bab0474f3a0bb30ab38"}, + {file = "protobuf-5.27.2-cp310-abi3-win_amd64.whl", hash = "sha256:0e341109c609749d501986b835f667c6e1e24531096cff9d34ae411595e26505"}, + {file = "protobuf-5.27.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a109916aaac42bff84702fb5187f3edadbc7c97fc2c99c5ff81dd15dcce0d1e5"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:176c12b1f1c880bf7a76d9f7c75822b6a2bc3db2d28baa4d300e8ce4cde7409b"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b848dbe1d57ed7c191dfc4ea64b8b004a3f9ece4bf4d0d80a367b76df20bf36e"}, + {file = "protobuf-5.27.2-cp38-cp38-win32.whl", hash = "sha256:4fadd8d83e1992eed0248bc50a4a6361dc31bcccc84388c54c86e530b7f58863"}, + {file = "protobuf-5.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:610e700f02469c4a997e58e328cac6f305f649826853813177e6290416e846c6"}, + {file = "protobuf-5.27.2-cp39-cp39-win32.whl", hash = "sha256:9e8f199bf7f97bd7ecebffcae45ebf9527603549b2b562df0fbc6d4d688f14ca"}, + {file = "protobuf-5.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:7fc3add9e6003e026da5fc9e59b131b8f22b428b991ccd53e2af8071687b4fce"}, + {file = "protobuf-5.27.2-py3-none-any.whl", hash = "sha256:54330f07e4949d09614707c48b06d1a22f8ffb5763c159efd5c0928326a91470"}, + {file = "protobuf-5.27.2.tar.gz", hash = "sha256:f3ecdef226b9af856075f28227ff2c90ce3a594d092c39bee5513573f25e2714"}, ] [[package]] @@ -868,13 +862,13 @@ setuptools = ">=42.0.0" [[package]] name = "pylint" -version = "3.2.3" +version = "3.2.5" description = "python code static checker" optional = false python-versions = ">=3.8.0" files = [ - {file = "pylint-3.2.3-py3-none-any.whl", hash = "sha256:b3d7d2708a3e04b4679e02d99e72329a8b7ee8afb8d04110682278781f889fa8"}, - {file = "pylint-3.2.3.tar.gz", hash = "sha256:02f6c562b215582386068d52a30f520d84fdbcf2a95fc7e855b816060d048b60"}, + {file = "pylint-3.2.5-py3-none-any.whl", hash = "sha256:32cd6c042b5004b8e857d727708720c54a676d1e22917cf1a2df9b4d4868abd6"}, + {file = "pylint-3.2.5.tar.gz", hash = "sha256:e9b7171e242dcc6ebd0aaa7540481d1a72860748a0a7816b8fe6cf6c80a6fe7e"}, ] [package.dependencies] @@ -1109,7 +1103,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1167,13 +1160,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "setuptools" -version = "70.1.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, - {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] @@ -1229,13 +1222,13 @@ files = [ [[package]] name = "types-protobuf" -version = "5.26.0.20240422" +version = "5.27.0.20240626" description = "Typing stubs for protobuf" optional = false python-versions = ">=3.8" files = [ - {file = "types-protobuf-5.26.0.20240422.tar.gz", hash = "sha256:e6074178109f97efe9f0b20a035ba61d7c3b03e867eb47d254d2b2ab6a805e36"}, - {file = "types_protobuf-5.26.0.20240422-py3-none-any.whl", hash = "sha256:e4dc2554d342501d5aebc3c71203868b51118340e105fc190e3a64ca1be43831"}, + {file = "types-protobuf-5.27.0.20240626.tar.gz", hash = "sha256:683ba14043bade6785e3f937a7498f243b37881a91ac8d81b9202ecf8b191e9c"}, + {file = "types_protobuf-5.27.0.20240626-py3-none-any.whl", hash = "sha256:688e8f7e8d9295db26bc560df01fb731b27a25b77cbe4c1ce945647f7024f5c1"}, ] [[package]] From 532ca54ba4a1494f12a78ec300b4588769df4f2f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 14:25:01 -0700 Subject: [PATCH 089/248] fix bug: we were never calling BLE.disconnect() which... on linux breaks all but the first connection attempts. Also remove unneeded event stuff and arbitrary timeouts, better just to use thread.join() --- meshtastic/ble_interface.py | 91 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 96293d0..0b5c8b7 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -1,14 +1,15 @@ """Bluetooth interface """ import asyncio +import atexit import logging import struct import time -from threading import Event, Thread +from threading import Thread from typing import Optional -from print_color import print from bleak import BleakClient, BleakScanner, BLEDevice +from print_color import print from meshtastic.mesh_interface import MeshInterface from meshtastic.util import our_exit @@ -20,18 +21,13 @@ FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453" LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" - class BLEInterface(MeshInterface): """MeshInterface using BLE to connect to devices.""" class BLEError(Exception): """An exception class for BLE errors.""" - pass - class BLEState: # pylint: disable=C0115 - THREADS = False - BLE = False - MESH = False + pass def __init__( self, @@ -40,23 +36,23 @@ class BLEInterface(MeshInterface): debugOut=None, noNodes: bool = False, ): - self.state = BLEInterface.BLEState() + MeshInterface.__init__( + self, debugOut=debugOut, noProto=noProto, noNodes=noNodes + ) self.should_read = False logging.debug("Threads starting") - self._receiveThread = Thread(target=self._receiveFromRadioImpl, name="BLEReceive", daemon=True) - self._receiveThread_started = Event() - self._receiveThread_stopped = Event() + self._want_receive = True + self._receiveThread: Optional[Thread] = Thread( + target=self._receiveFromRadioImpl, name="BLEReceive", daemon=True + ) self._receiveThread.start() - self._receiveThread_started.wait(1) - self.state.THREADS = True logging.debug("Threads running") try: logging.debug(f"BLE connecting to: {address if address else 'any'}") - self.client = self.connect(address) - self.state.BLE = True + self.client: Optional[BLEClient] = self.connect(address) logging.debug("BLE connected") except BLEInterface.BLEError as e: self.close() @@ -64,29 +60,30 @@ class BLEInterface(MeshInterface): self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) - logging.debug("Mesh init starting") - MeshInterface.__init__( - self, debugOut=debugOut, noProto=noProto, noNodes=noNodes - ) + logging.debug("Mesh configure starting") self._startConfig() if not self.noProto: self._waitConnected(timeout=60.0) self.waitForConfig() - self.state.MESH = True logging.debug("Mesh init finished") 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 + # and future connection attempts will fail. (BlueZ kinda sucks) + self._exit_handler = atexit.register(self.close) + def from_num_handler(self, _, b): # pylint: disable=C0116 """Handle callbacks for fromnum notify. - Note: this method does not need to be async because it is just setting a bool.""" + Note: this method does not need to be async because it is just setting a bool. + """ from_num = struct.unpack(" Date: Sat, 29 Jun 2024 14:37:50 -0700 Subject: [PATCH 090/248] fix linter warnings --- meshtastic/__main__.py | 3 +-- meshtastic/ble_interface.py | 17 +++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 8bebf41..7458e66 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1044,7 +1044,6 @@ def common(): for x in BLEInterface.scan(): print(f"Found: name='{x.name}' address='{x.address}'") meshtastic.util.our_exit("BLE scan finished", 0) - return elif args.ble: client = BLEInterface(args.ble_dest, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) elif args.host: @@ -1122,7 +1121,7 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse "--ble-dest", help="The BLE device address or name to connect to", default=None, - ) + ) return parser diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 0b5c8b7..4c24528 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -9,10 +9,9 @@ from threading import Thread from typing import Optional from bleak import BleakClient, BleakScanner, BLEDevice -from print_color import print +import print_color from meshtastic.mesh_interface import MeshInterface -from meshtastic.util import our_exit SERVICE_UUID = "6ba1b218-15a8-461f-9fa8-5dcae273eafd" TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7" @@ -27,8 +26,6 @@ class BLEInterface(MeshInterface): class BLEError(Exception): """An exception class for BLE errors.""" - pass - def __init__( self, address: Optional[str], @@ -85,15 +82,15 @@ class BLEInterface(MeshInterface): async def log_radio_handler(self, _, b): # pylint: disable=C0116 log_radio = b.decode("utf-8").replace("\n", "") if log_radio.startswith("DEBUG"): - print(log_radio, color="cyan", end=None) + print_color.print(log_radio, color="cyan", end=None) elif log_radio.startswith("INFO"): - print(log_radio, color="white", end=None) + print_color.print(log_radio, color="white", end=None) elif log_radio.startswith("WARN"): - print(log_radio, color="yellow", end=None) + print_color.print(log_radio, color="yellow", end=None) elif log_radio.startswith("ERROR"): - print(log_radio, color="red", end=None) + print_color.print(log_radio, color="red", end=None) else: - print(log_radio, end=None) + print_color.print(log_radio, end=None) @staticmethod def scan() -> list[BLEDevice]: @@ -122,7 +119,7 @@ class BLEInterface(MeshInterface): if address: addressed_devices = list( filter( - lambda x: address == x.name or address == x.address, + lambda x: address in (x.name, x.address), addressed_devices, ) ) From bd767af4857022caab2f7ea51fe076ef0c384b45 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 15:08:50 -0700 Subject: [PATCH 091/248] A better way to ensure BLE disconnects: It turns out that Bleak is kinda racey. If we call disconnect() and then immediately close() the disconnect may or may not actually happen (probably because it was merely queued for dbus). So instead: When we want to close the BLEInterface we call disconnect() and then in a preregistered 'on disconnect' handler we actually close down our interface/datastructures. --- meshtastic/ble_interface.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 4c24528..4357a4b 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -8,8 +8,9 @@ import time from threading import Thread from typing import Optional -from bleak import BleakClient, BleakScanner, BLEDevice import print_color +from bleak import BleakClient, BleakScanner, BLEDevice +from bleak.exc import BleakDBusError, BleakError from meshtastic.mesh_interface import MeshInterface @@ -62,14 +63,14 @@ class BLEInterface(MeshInterface): if not self.noProto: self._waitConnected(timeout=60.0) self.waitForConfig() - logging.debug("Mesh init finished") 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 # and future connection attempts will fail. (BlueZ kinda sucks) - self._exit_handler = atexit.register(self.close) + # 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 from_num_handler(self, _, b): # pylint: disable=C0116 """Handle callbacks for fromnum notify. @@ -143,7 +144,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) + client = BLEClient(device.address, disconnected_callback=lambda _: self.close) client.connect() client.discover() return client @@ -153,11 +154,20 @@ class BLEInterface(MeshInterface): if self.should_read: self.should_read = False retries = 0 - while True: + while self._want_receive: try: b = bytes(self.client.read_gatt_char(FROMRADIO_UUID)) - except Exception as e: - raise BLEInterface.BLEError("Error reading BLE") from e + except BleakDBusError as e: + # Device disconnected probably, so end our read loop immediately + 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): + logging.debug(f"Device disconnected, shutting down {e}") + self._want_receive = False + else: + raise BLEInterface.BLEError("Error reading BLE") from e if not b: if retries < 5: time.sleep(0.1) @@ -188,7 +198,10 @@ class BLEInterface(MeshInterface): def close(self): atexit.unregister(self._exit_handler) - MeshInterface.close(self) + try: + MeshInterface.close(self) + except Exception as 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 From 9004f1ed57155fcbc040016918fca6a17d657781 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 15:12:11 -0700 Subject: [PATCH 092/248] fixes for type checker --- meshtastic/ble_interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 4357a4b..69cb9a3 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -8,7 +8,7 @@ import time from threading import Thread from typing import Optional -import print_color +import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError @@ -139,7 +139,7 @@ class BLEInterface(MeshInterface): "Standardize BLE address by removing extraneous characters and lowercasing." return address.replace("-", "").replace("_", "").replace(":", "").lower() - def connect(self, address: Optional[str] = None): + def connect(self, address: Optional[str] = None) -> "BLEClient": "Connect to a device by address." # Bleak docs recommend always doing a scan before connecting (even if we know addr) From 1da687cf2d8ff731551584bd12eef31df9001093 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 29 Jun 2024 16:15:32 -0700 Subject: [PATCH 093/248] move @thebentern spiffy logging so it is shared with !ble log sources --- meshtastic/ble_interface.py | 12 +----------- meshtastic/mesh_interface.py | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 69cb9a3..1ebc57b 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -8,7 +8,6 @@ import time from threading import Thread from typing import Optional -import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError @@ -82,16 +81,7 @@ class BLEInterface(MeshInterface): async def log_radio_handler(self, _, b): # pylint: disable=C0116 log_radio = b.decode("utf-8").replace("\n", "") - if log_radio.startswith("DEBUG"): - print_color.print(log_radio, color="cyan", end=None) - elif log_radio.startswith("INFO"): - print_color.print(log_radio, color="white", end=None) - elif log_radio.startswith("WARN"): - print_color.print(log_radio, color="yellow", end=None) - elif log_radio.startswith("ERROR"): - print_color.print(log_radio, color="red", end=None) - else: - print_color.print(log_radio, end=None) + self._handleLogLine(log_radio) @staticmethod def scan() -> list[BLEDevice]: diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 38eca07..2c0ceeb 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -16,6 +16,7 @@ from typing import Any, Callable, Dict, List, Optional, Union import google.protobuf.json_format from pubsub import pub # type: ignore[import-untyped] from tabulate import tabulate +import print_color # type: ignore[import-untyped] import meshtastic.node @@ -143,8 +144,21 @@ class MeshInterface: # pylint: disable=R0902 @staticmethod def _printLogLine(line, interface): - """Print a line of log output""" - interface.debugOut.write(line + "\n") + """Print a line of log output.""" + if interface.debugOut == sys.stdout: + # this isn't quite correct (could cause false positives), but currently our formatting differs between different log representations + if "DEBUG" in line: + print_color.print(line, color="cyan", end=None) + elif "INFO" in line: + print_color.print(line, color="white", end=None) + elif "WARN" in line: + print_color.print(line, color="yellow", end=None) + elif "ERR" in line: + print_color.print(line, color="red", end=None) + else: + print_color.print(line, end=None) + else: + interface.debugOut.write(line + "\n") def _handleLogLine(self, line: str) -> None: """Handle a line of log output from the device.""" From a3afc2ae0ad0760773a1b9821a632534f32f79ee Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 29 Jun 2024 17:34:02 -0700 Subject: [PATCH 094/248] Ensure regen-protobufs works if there's no pre-existing directory to remove --- bin/regen-protobufs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index a41f7ba..4a3d179 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -15,7 +15,7 @@ echo "Fixing up protobuf paths in ${TMPDIR} temp directory" # Ensure a clean build -rm -r "${TMPDIR}" +[ -e "${TMPDIR}" ] && rm -r "${TMPDIR}" INDIR=${TMPDIR}/in/meshtastic/protobuf OUTDIR=${TMPDIR}/out From 18c2d08bf0ef5c17bf10e6e0d2bde00221bda0e9 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 29 Jun 2024 17:36:22 -0700 Subject: [PATCH 095/248] protobufs: v2.3.13 --- meshtastic/protobuf/admin_pb2.py | 20 +++---- meshtastic/protobuf/admin_pb2.pyi | 12 +++- meshtastic/protobuf/config_pb2.py | 44 ++++++++------- meshtastic/protobuf/config_pb2.pyi | 81 ++++++++++++++++++++++++++- meshtastic/protobuf/mesh_pb2.py | 12 ++-- meshtastic/protobuf/mesh_pb2.pyi | 16 ++++++ meshtastic/protobuf/telemetry_pb2.py | 22 ++++---- meshtastic/protobuf/telemetry_pb2.pyi | 44 ++++++++++++++- protobufs | 2 +- 9 files changed, 200 insertions(+), 53 deletions(-) diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index 1429f1e..c002b8f 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -18,7 +18,7 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xd5\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xea\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,13 +27,13 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_ADMINMESSAGE']._serialized_start=244 - _globals['_ADMINMESSAGE']._serialized_end=2633 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2147 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2296 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2299 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2614 - _globals['_HAMPARAMETERS']._serialized_start=2635 - _globals['_HAMPARAMETERS']._serialized_end=2726 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2728 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2839 + _globals['_ADMINMESSAGE']._serialized_end=2654 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2168 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2317 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2320 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2635 + _globals['_HAMPARAMETERS']._serialized_start=2656 + _globals['_HAMPARAMETERS']._serialized_end=2747 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2749 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2860 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index cdfc6b7..0840385 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -241,6 +241,7 @@ class AdminMessage(google.protobuf.message.Message): GET_NODE_REMOTE_HARDWARE_PINS_RESPONSE_FIELD_NUMBER: builtins.int ENTER_DFU_MODE_REQUEST_FIELD_NUMBER: builtins.int DELETE_FILE_REQUEST_FIELD_NUMBER: builtins.int + SET_SCALE_FIELD_NUMBER: builtins.int SET_OWNER_FIELD_NUMBER: builtins.int SET_CHANNEL_FIELD_NUMBER: builtins.int SET_CONFIG_FIELD_NUMBER: builtins.int @@ -314,6 +315,10 @@ class AdminMessage(google.protobuf.message.Message): """ Delete the file by the specified path from the device """ + set_scale: builtins.int + """ + Set zero and offset for scale chips + """ set_canned_message_module_messages: builtins.str """ Set the Canned Message Module messages text. @@ -479,6 +484,7 @@ class AdminMessage(google.protobuf.message.Message): get_node_remote_hardware_pins_response: global___NodeRemoteHardwarePinsResponse | None = ..., enter_dfu_mode_request: builtins.bool = ..., delete_file_request: builtins.str = ..., + set_scale: builtins.int = ..., set_owner: meshtastic.protobuf.mesh_pb2.User | None = ..., set_channel: meshtastic.protobuf.channel_pb2.Channel | None = ..., set_config: meshtastic.protobuf.config_pb2.Config | None = ..., @@ -499,9 +505,9 @@ class AdminMessage(google.protobuf.message.Message): factory_reset: builtins.int = ..., nodedb_reset: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "shutdown_seconds", b"shutdown_seconds"]) -> 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_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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... + def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> 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", "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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... global___AdminMessage = AdminMessage diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index c385527..2a18126 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xed \n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xe2\x05\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\x85#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,7 +26,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=4263 + _globals['_CONFIG']._serialized_end=4543 _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 _globals['_CONFIG_DEVICECONFIG']._serialized_end=1172 _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 @@ -48,23 +48,25 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2446 _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2481 _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2484 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3222 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=2957 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3034 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3036 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3076 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3078 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3155 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3157 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3222 - _globals['_CONFIG_LORACONFIG']._serialized_start=3225 - _globals['_CONFIG_LORACONFIG']._serialized_end=4059 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=3703 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=3908 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=3911 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4059 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4062 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4244 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4188 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4244 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3502 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3048 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3125 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3127 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3167 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3169 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3246 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3248 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3313 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3316 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3502 + _globals['_CONFIG_LORACONFIG']._serialized_start=3505 + _globals['_CONFIG_LORACONFIG']._serialized_end=4339 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=3983 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4188 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4191 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4339 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4342 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4524 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4468 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4524 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 49d64de..776a627 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -960,6 +960,79 @@ class Config(google.protobuf.message.Message): TFT Full Color Displays (not implemented yet) """ + class _CompassOrientation: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _CompassOrientationEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._CompassOrientation.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DEGREES_0: Config.DisplayConfig._CompassOrientation.ValueType # 0 + """ + The compass and the display are in the same orientation. + """ + DEGREES_90: Config.DisplayConfig._CompassOrientation.ValueType # 1 + """ + Rotate the compass by 90 degrees. + """ + DEGREES_180: Config.DisplayConfig._CompassOrientation.ValueType # 2 + """ + Rotate the compass by 180 degrees. + """ + DEGREES_270: Config.DisplayConfig._CompassOrientation.ValueType # 3 + """ + Rotate the compass by 270 degrees. + """ + DEGREES_0_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 4 + """ + Don't rotate the compass, but invert the result. + """ + DEGREES_90_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 5 + """ + Rotate the compass by 90 degrees and invert. + """ + DEGREES_180_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 6 + """ + Rotate the compass by 180 degrees and invert. + """ + DEGREES_270_INVERTED: Config.DisplayConfig._CompassOrientation.ValueType # 7 + """ + Rotate the compass by 270 degrees and invert. + """ + + class CompassOrientation(_CompassOrientation, metaclass=_CompassOrientationEnumTypeWrapper): ... + DEGREES_0: Config.DisplayConfig.CompassOrientation.ValueType # 0 + """ + The compass and the display are in the same orientation. + """ + DEGREES_90: Config.DisplayConfig.CompassOrientation.ValueType # 1 + """ + Rotate the compass by 90 degrees. + """ + DEGREES_180: Config.DisplayConfig.CompassOrientation.ValueType # 2 + """ + Rotate the compass by 180 degrees. + """ + DEGREES_270: Config.DisplayConfig.CompassOrientation.ValueType # 3 + """ + Rotate the compass by 270 degrees. + """ + DEGREES_0_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 4 + """ + Don't rotate the compass, but invert the result. + """ + DEGREES_90_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 5 + """ + Rotate the compass by 90 degrees and invert. + """ + DEGREES_180_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 6 + """ + Rotate the compass by 180 degrees and invert. + """ + DEGREES_270_INVERTED: Config.DisplayConfig.CompassOrientation.ValueType # 7 + """ + Rotate the compass by 270 degrees and invert. + """ + SCREEN_ON_SECS_FIELD_NUMBER: builtins.int GPS_FORMAT_FIELD_NUMBER: builtins.int AUTO_SCREEN_CAROUSEL_SECS_FIELD_NUMBER: builtins.int @@ -970,6 +1043,7 @@ class Config(google.protobuf.message.Message): DISPLAYMODE_FIELD_NUMBER: builtins.int HEADING_BOLD_FIELD_NUMBER: builtins.int WAKE_ON_TAP_OR_MOTION_FIELD_NUMBER: builtins.int + COMPASS_ORIENTATION_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 @@ -1013,6 +1087,10 @@ class Config(google.protobuf.message.Message): """ Should we wake the screen up on accelerometer detected motion or tap """ + compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType + """ + Indicates how to rotate or invert the compass output to accurate display on the display. + """ def __init__( self, *, @@ -1026,8 +1104,9 @@ class Config(google.protobuf.message.Message): displaymode: global___Config.DisplayConfig.DisplayMode.ValueType = ..., heading_bold: builtins.bool = ..., wake_on_tap_or_motion: builtins.bool = ..., + compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "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", "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", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... @typing.final class LoRaConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 684b513..23d1004 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xeb\x08\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x96\t\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,11 +32,11 @@ if _descriptor._USE_C_DESCRIPTORS == False: _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' _globals['_HARDWAREMODEL']._serialized_start=5442 - _globals['_HARDWAREMODEL']._serialized_end=6573 - _globals['_CONSTANTS']._serialized_start=6575 - _globals['_CONSTANTS']._serialized_end=6619 - _globals['_CRITICALERRORCODE']._serialized_start=6622 - _globals['_CRITICALERRORCODE']._serialized_end=6860 + _globals['_HARDWAREMODEL']._serialized_end=6616 + _globals['_CONSTANTS']._serialized_start=6618 + _globals['_CONSTANTS']._serialized_end=6662 + _globals['_CRITICALERRORCODE']._serialized_start=6665 + _globals['_CRITICALERRORCODE']._serialized_end=6903 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 89b0a75..6c984e9 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -121,6 +121,10 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk """ + RAK2560: _HardwareModel.ValueType # 22 + """ + RAK2560 Solar base station based on RAK4630 + """ STATION_G1: _HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -295,6 +299,10 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS """ + HELTEC_CAPSULE_SENSOR_V3: _HardwareModel.ValueType # 65 + """ + Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -400,6 +408,10 @@ WIO_WM1110: HardwareModel.ValueType # 21 """ WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk """ +RAK2560: HardwareModel.ValueType # 22 +""" +RAK2560 Solar base station based on RAK4630 +""" STATION_G1: HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -574,6 +586,10 @@ RADIOMASTER_900_BANDIT_NANO: HardwareModel.ValueType # 64 RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS """ +HELTEC_CAPSULE_SENSOR_V3: HardwareModel.ValueType # 65 +""" +Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 9c2cf4e..5a1188d 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xa6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant*\xdd\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xb6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,16 +21,18 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemet if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=1259 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=1608 + _globals['_TELEMETRYSENSORTYPE']._serialized_start=1339 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=1701 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=190 _globals['_ENVIRONMENTMETRICS']._serialized_start=193 - _globals['_ENVIRONMENTMETRICS']._serialized_end=487 - _globals['_POWERMETRICS']._serialized_start=490 - _globals['_POWERMETRICS']._serialized_end=630 - _globals['_AIRQUALITYMETRICS']._serialized_start=633 - _globals['_AIRQUALITYMETRICS']._serialized_end=952 - _globals['_TELEMETRY']._serialized_start=955 - _globals['_TELEMETRY']._serialized_end=1256 + _globals['_ENVIRONMENTMETRICS']._serialized_end=503 + _globals['_POWERMETRICS']._serialized_start=506 + _globals['_POWERMETRICS']._serialized_end=646 + _globals['_AIRQUALITYMETRICS']._serialized_start=649 + _globals['_AIRQUALITYMETRICS']._serialized_end=968 + _globals['_TELEMETRY']._serialized_start=971 + _globals['_TELEMETRY']._serialized_end=1272 + _globals['_NAU7802CONFIG']._serialized_start=1274 + _globals['_NAU7802CONFIG']._serialized_end=1336 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index aba51c8..fb0f4dd 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -123,6 +123,10 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) """ + NAU7802: _TelemetrySensorType.ValueType # 25 + """ + NAU7802 Scale Chip or compatible + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -229,6 +233,10 @@ DFROBOT_LARK: TelemetrySensorType.ValueType # 24 """ DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) """ +NAU7802: TelemetrySensorType.ValueType # 25 +""" +NAU7802 Scale Chip or compatible +""" global___TelemetrySensorType = TelemetrySensorType @typing.final @@ -299,6 +307,7 @@ class EnvironmentMetrics(google.protobuf.message.Message): UV_LUX_FIELD_NUMBER: builtins.int WIND_DIRECTION_FIELD_NUMBER: builtins.int WIND_SPEED_FIELD_NUMBER: builtins.int + WEIGHT_FIELD_NUMBER: builtins.int temperature: builtins.float """ Temperature measured @@ -357,6 +366,10 @@ class EnvironmentMetrics(google.protobuf.message.Message): """ Wind speed in m/s """ + weight: builtins.float + """ + Weight in KG + """ def __init__( self, *, @@ -374,8 +387,9 @@ class EnvironmentMetrics(google.protobuf.message.Message): uv_lux: builtins.float = ..., wind_direction: builtins.int = ..., wind_speed: builtins.float = ..., + weight: builtins.float = ..., ) -> None: ... - 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", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_speed", b"wind_speed"]) -> None: ... + 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", "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_speed", b"wind_speed"]) -> None: ... global___EnvironmentMetrics = EnvironmentMetrics @@ -574,3 +588,31 @@ class Telemetry(google.protobuf.message.Message): def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics"] | None: ... global___Telemetry = Telemetry + +@typing.final +class Nau7802Config(google.protobuf.message.Message): + """ + NAU7802 Telemetry configuration, for saving to flash + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ZEROOFFSET_FIELD_NUMBER: builtins.int + CALIBRATIONFACTOR_FIELD_NUMBER: builtins.int + zeroOffset: builtins.int + """ + The offset setting for the NAU7802 + """ + calibrationFactor: builtins.float + """ + The calibration factor for the NAU7802 + """ + def __init__( + self, + *, + zeroOffset: builtins.int = ..., + calibrationFactor: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["calibrationFactor", b"calibrationFactor", "zeroOffset", b"zeroOffset"]) -> None: ... + +global___Nau7802Config = Nau7802Config diff --git a/protobufs b/protobufs index a641c5c..0c90a68 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a641c5ce4fca158d18ca3cffc92ac7a10f9b6a04 +Subproject commit 0c90a6814fdd959a35bb6cf8e958e74d48e8a601 From 13ca8fd68144342f83ba2a942cc7b0defcf77b6d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 30 Jun 2024 06:31:09 -0700 Subject: [PATCH 096/248] debug launch configs --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ae7616b..7cbe3b0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--ble", "--ble-dest", "Meshtastic_9f6e"] + "args": ["--ble", "--info", "--seriallog", "stdout"] }, { "name": "meshtastic BLE scan", From 5c2851db858deba184fdd3bc3c6de8f19024d6cf Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 30 Jun 2024 06:46:39 -0700 Subject: [PATCH 097/248] nargs='?' is awesome! get rid of ble_dest. --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6c9c892..e2534db 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--ble", "--ble-dest", "Meshtastic_9f6e"] + "args": ["--ble", "Meshtastic_9f6e"] }, { "name": "meshtastic BLE scan", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index e58910a..173d6e0 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1046,7 +1046,7 @@ def common(): print(f"Found: name='{x.name}' address='{x.address}'") meshtastic.util.our_exit("BLE scan finished", 0) elif args.ble: - client = BLEInterface(args.ble_dest, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) + client = BLEInterface(args.ble if args.ble != "any" else None, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) elif args.host: try: client = meshtastic.tcp_interface.TCPInterface( @@ -1114,14 +1114,10 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse group.add_argument( "--ble", - help="The BLE device address or name to connect to", - action="store_true", - ) - - outer.add_argument( - "--ble-dest", - help="The BLE device address or name to connect to", + help="Connect to a BLE device, optionally specifying a device name (defaults to 'any')", + nargs="?", default=None, + const="any" ) return parser From a04b3498b348c4b34507cc5d81309b5bd64941ee Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 30 Jun 2024 06:54:29 -0700 Subject: [PATCH 098/248] make specifying an argument to --seriallog optional thanks @ianmcorvidae for telling me about the cool nargs='?' option! --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index aca86dd..b919550 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -164,7 +164,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": true, - "args": ["--debug", "--seriallog", "stdout"] + "args": ["--debug", "--seriallog"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 781f6bf..2f5ef2f 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1170,7 +1170,10 @@ def initParser(): group.add_argument( "--seriallog", - help="Log device serial output to either 'stdout', 'none' or a filename to append to.", + help="Log device serial output to either 'none' or a filename to append to. Defaults to 'stdout' if no filename specified.", + nargs='?', + const="stdout", + default=None ) group.add_argument( From a68a9f85171b6984492144a82986fbdbd830c260 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 30 Jun 2024 07:12:09 -0700 Subject: [PATCH 099/248] Add bin/git-resolve-poetry-lock.sh to resolve merge conficts Previously I was just doing poetry update to resolve such conflicts, but that's not really ideal because it updates all libs. poetry lock --no-update is better, but even better to base the changes from their version of poetry-lock and then add only my changes as required by pyproject.yaml. You can use this script if you get a merge conflict with poetry.lock and it will just do the right thing. btw: in my powermon/structuredlogging branch I have a commit to add support for the "poe" tool which will provide a shortcut for this script. --- bin/git-resolve-poetry-lock.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 bin/git-resolve-poetry-lock.sh diff --git a/bin/git-resolve-poetry-lock.sh b/bin/git-resolve-poetry-lock.sh new file mode 100755 index 0000000..e47fad5 --- /dev/null +++ b/bin/git-resolve-poetry-lock.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e + +# This is a little helper you can use to resolve git merge conflicts in poetry.lock +# with minimal changes vs the requested lib versions +# Based on this article with a good description of best practices: +# https://www.peterbe.com/plog/how-to-resolve-a-git-conflict-in-poetry.lock + +echo "Resolving poetry.lock merge conflicts, you'll need to run git commit yourself..." + +# Get poetry.lock to look like it does in master +git checkout --theirs poetry.lock +# Rewrite the lock file +poetry lock --no-update +git add poetry.lock + +# Update your poetry env to match the new merged lock file +poetry install From e331bea4ea8a94db943ec828844f119b99c3af41 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 09:58:32 -0700 Subject: [PATCH 100/248] make typing a little more 3.8-approved --- meshtastic/ble_interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 69cb9a3..bb6e8ec 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -6,7 +6,7 @@ import logging import struct import time from threading import Thread -from typing import Optional +from typing import List, Optional import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice @@ -94,7 +94,7 @@ class BLEInterface(MeshInterface): print_color.print(log_radio, end=None) @staticmethod - def scan() -> list[BLEDevice]: + def scan() -> List[BLEDevice]: """Scan for available BLE devices.""" with BLEClient() as client: logging.info("Scanning for BLE devices (takes 10 seconds)...") From 93fbc78492783f6ced2eed18de5801ec3297ce83 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 10:04:54 -0700 Subject: [PATCH 101/248] Properly handle missing nodes in traceroute response (fixes #612) --- meshtastic/mesh_interface.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 49e87fd..bf7d715 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -490,11 +490,11 @@ class MeshInterface: # pylint: disable=R0902 asDict = google.protobuf.json_format.MessageToDict(routeDiscovery) print("Route traced:") - routeStr = self._nodeNumToId(p["to"]) + routeStr = self._nodeNumToId(p["to"]) or f"{p['to']:08x}" if "route" in asDict: for nodeNum in asDict["route"]: - routeStr += " --> " + self._nodeNumToId(nodeNum) - routeStr += " --> " + self._nodeNumToId(p["from"]) + routeStr += " --> " + (self._nodeNumToId(nodeNum) or f"{nodeNum:08x}") + routeStr += " --> " + (self._nodeNumToId(p["from"]) or f"{p['from']:08x}") print(routeStr) self._acknowledgment.receivedTraceRoute = True @@ -1021,7 +1021,7 @@ class MeshInterface: # pylint: disable=R0902 position["longitude"] = float(position["longitudeI"] * Decimal("1e-7")) return position - def _nodeNumToId(self, num): + def _nodeNumToId(self, num: int) -> Optional[str]: """Map a node node number to a node ID Arguments: @@ -1034,7 +1034,7 @@ class MeshInterface: # pylint: disable=R0902 return BROADCAST_ADDR try: - return self.nodesByNum[num]["user"]["id"] + return self.nodesByNum[num]["user"]["id"] #type: ignore[index] except: logging.debug(f"Node {num} not found for fromId") return None From 111d61ea0ac4c121104d6ec0090b891c15fff7d0 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 30 Jun 2024 13:00:12 -0700 Subject: [PATCH 102/248] bleak reads can hang if a device walks out of range, cope with that. --- meshtastic/ble_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index bb6e8ec..b5f9f7d 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -205,7 +205,7 @@ class BLEInterface(MeshInterface): if self._want_receive: self.want_receive = False # Tell the thread we want it to stop - self._receiveThread.join() + self._receiveThread.join(timeout=2) # If bleak is hung, don't wait for the thread to exit (it is critical we disconnect) self._receiveThread = None if self.client: From abdfbc673efa4abb68d5208fbfb6c3aba50cfb31 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 16:52:31 -0700 Subject: [PATCH 103/248] Allow connection args without an argument, add argument aliases --- meshtastic/__main__.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 93b3ba9..cc9cff0 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1101,20 +1101,24 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse outer = parser.add_argument_group('Connection', 'Optional arguments that specify how to connect to a Meshtastic device.') group = outer.add_mutually_exclusive_group() group.add_argument( - "--port", - help="The port of the device to connect to using serial, e.g. /dev/ttyUSB0.", + "--port", "--serial", "-s", + help="The port of the device to connect to using serial, e.g. /dev/ttyUSB0. (defaults to trying to detect a port)", + nargs="?", + const=None, default=None, ) group.add_argument( - "--host", - help="The hostname or IP address of the device to connect to using TCP", + "--host", "--tcp", "-t", + help="Connect to a device using TCP, optionally passing hostname or IP address to use. (defaults to '%(const)s')", + nargs="?", default=None, + const="localhost" ) group.add_argument( - "--ble", - help="Connect to a BLE device, optionally specifying a device name (defaults to 'any')", + "--ble", "-b", + help="Connect to a BLE device, optionally specifying a device name (defaults to '%(const)s')", nargs="?", default=None, const="any" From 9ffdc30c1f0bcfe5eec1a2ff645ee3625a9f99f6 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 23:25:07 -0700 Subject: [PATCH 104/248] Make remote hardware args live in their own little box --- meshtastic/__main__.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index cc9cff0..45c4345 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1442,16 +1442,6 @@ def initParser(): "--reply", help="Reply to received messages", action="store_true" ) - group.add_argument( - "--gpio-wrb", nargs=2, help="Set a particular GPIO # to 1 or 0", action="append" - ) - - group.add_argument("--gpio-rd", help="Read from a GPIO mask (ex: '0x10')") - - group.add_argument( - "--gpio-watch", help="Start watching a GPIO mask for changes (ex: '0x10')" - ) - group.add_argument( "--no-time", help="Suppress sending the current time to the mesh", @@ -1531,6 +1521,21 @@ def initParser(): action="store_true", ) + remoteHardwareArgs = parser.add_argument_group('Remote Hardware', 'Arguments related to the Remote Hardware module') + + remoteHardwareArgs.add_argument( + "--gpio-wrb", nargs=2, help="Set a particular GPIO # to 1 or 0", action="append" + ) + + remoteHardwareArgs.add_argument( + "--gpio-rd", help="Read from a GPIO mask (ex: '0x10')" + ) + + remoteHardwareArgs.add_argument( + "--gpio-watch", help="Start watching a GPIO mask for changes (ex: '0x10')" + ) + + have_tunnel = platform.system() == "Linux" if have_tunnel: tunnelArgs = parser.add_argument_group('Tunnel', 'Arguments related to establishing a tunnel device over the mesh.') From 33c5be5219d70323a81d4326165fb8bdea450519 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 23:25:57 -0700 Subject: [PATCH 105/248] Update doc string for --pos-fields to use valid values --- meshtastic/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 45c4345..c032a36 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1480,7 +1480,7 @@ def initParser(): "--pos-fields", help="Specify fields to send when sending a position. Use no argument for a list of valid values. " "Can pass multiple values as a space separated list like " - "this: '--pos-fields POS_ALTITUDE POS_ALT_MSL'", + "this: '--pos-fields ALTITUDE HEADING SPEED'", nargs="*", action="store", ) From 49bd9cb515fbbafce71860436783f2596dd241d9 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 30 Jun 2024 23:40:11 -0700 Subject: [PATCH 106/248] Support --ble on older firmwares that don't have the log-radio characteristic yet. --- meshtastic/ble_interface.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index b5f9f7d..c57930a 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -56,7 +56,8 @@ class BLEInterface(MeshInterface): self.close() raise e - self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) + if self.client.has_characteristic(LOGRADIO_UUID): + self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) logging.debug("Mesh configure starting") self._startConfig() @@ -248,6 +249,12 @@ class BLEClient: def write_gatt_char(self, *args, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.write_gatt_char(*args, **kwargs)) + def has_characteristic(self, specifier): + if self.bleak_client.services.get_characteristic(specifier): + return True + else: + return False + def start_notify(self, *args, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.start_notify(*args, **kwargs)) From 3b4690e93299731f214153ad36f0ff6f3da2e5c5 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Mon, 1 Jul 2024 00:00:59 -0700 Subject: [PATCH 107/248] appease the linter --- meshtastic/ble_interface.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index c57930a..885502f 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -250,10 +250,8 @@ class BLEClient: self.async_await(self.bleak_client.write_gatt_char(*args, **kwargs)) def has_characteristic(self, specifier): - if self.bleak_client.services.get_characteristic(specifier): - return True - else: - return False + """Check if the connected node supports a specified characteristic.""" + return bool(self.bleak_client.services.get_characteristic(specifier)) def start_notify(self, *args, **kwargs): # pylint: disable=C0116 self.async_await(self.bleak_client.start_notify(*args, **kwargs)) From 188f9d593c0c73e5be582711032d943d59fa0539 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 Jul 2024 06:16:49 -0500 Subject: [PATCH 108/248] Add handler for new log-record BLE characteristic --- meshtastic/ble_interface.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index b5f9f7d..bb30470 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -8,6 +8,10 @@ import time from threading import Thread from typing import List, Optional +from .protobuf import ( + mesh_pb2, +) + import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError @@ -18,7 +22,8 @@ SERVICE_UUID = "6ba1b218-15a8-461f-9fa8-5dcae273eafd" TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7" FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002" FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453" -LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" +LEGACY_LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" +LOGRADIO_UUID = "5a3d6e49-06e6-4423-9944-e9de8cdf9547" class BLEInterface(MeshInterface): @@ -56,6 +61,7 @@ class BLEInterface(MeshInterface): self.close() raise e + #self.client.start_notify(LEGACY_LOGRADIO_UUID, self.legacy_log_radio_handler) self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) logging.debug("Mesh configure starting") @@ -81,6 +87,22 @@ class BLEInterface(MeshInterface): self.should_read = True async def log_radio_handler(self, _, b): # pylint: disable=C0116 + if b is not mesh_pb2.LogRecord: + return + + log_record = b + if log_record.DEBUG: + print_color.print(log_record.message, color="cyan", end=None) + elif log_record.INFO: + print_color.print(log_record.message, color="white", end=None) + elif log_record.WARNING: + print_color.print(log_record.message, color="yellow", end=None) + elif log_record.ERROR: + print_color.print(log_record.message, color="red", end=None) + else: + print_color.print(log_record.message, end=None) + + async def legacy_log_radio_handler(self, _, b): # pylint: disable=C0116 log_radio = b.decode("utf-8").replace("\n", "") if log_radio.startswith("DEBUG"): print_color.print(log_radio, color="cyan", end=None) From bef9b480f01ebceda375aa37da21006fd0af04f2 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 Jul 2024 18:05:15 -0500 Subject: [PATCH 109/248] Log Recod logging with new characterstic --- meshtastic/ble_interface.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index e0566aa..34c7e75 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -90,20 +90,22 @@ class BLEInterface(MeshInterface): self.should_read = True async def log_radio_handler(self, _, b): # pylint: disable=C0116 - if b is not mesh_pb2.LogRecord: - return + log_record = mesh_pb2.LogRecord() + log_record.ParseFromString(bytes(b)) + log_record.message.replace("\n", "") + + message = f'[{log_record.source}] {log_record.message}' if log_record.source else log_record.message - log_record = b if log_record.DEBUG: - print_color.print(log_record.message, color="cyan", end=None) + print_color.print(message, color="cyan", end=None) elif log_record.INFO: - print_color.print(log_record.message, color="white", end=None) + print_color.print(message, color="white", end=None) elif log_record.WARNING: - print_color.print(log_record.message, color="yellow", end=None) + print_color.print(message, color="yellow", end=None) elif log_record.ERROR: - print_color.print(log_record.message, color="red", end=None) + print_color.print(message, color="red", end=None) else: - print_color.print(log_record.message, end=None) + print_color.print(message, end=None) async def legacy_log_radio_handler(self, _, b): # pylint: disable=C0116 log_radio = b.decode("utf-8").replace("\n", "") From ce6c096c3e584947b4b1f3814fc9776284e5b795 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 Jul 2024 21:05:27 -0500 Subject: [PATCH 110/248] Fix --- meshtastic/ble_interface.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 34c7e75..b63635d 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -7,12 +7,13 @@ import struct import time from threading import Thread from typing import List, Optional +import print_color # type: ignore[import-untyped] from .protobuf import ( mesh_pb2, ) +import google.protobuf -import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError @@ -91,8 +92,11 @@ class BLEInterface(MeshInterface): async def log_radio_handler(self, _, b): # pylint: disable=C0116 log_record = mesh_pb2.LogRecord() - log_record.ParseFromString(bytes(b)) - log_record.message.replace("\n", "") + try: + log_record.ParseFromString(bytes(b)) + log_record.message = log_record.message.replace("\n", "") + except google.protobuf.message.DecodeError: + return message = f'[{log_record.source}] {log_record.message}' if log_record.source else log_record.message From 19363967f358d8d3cbe95e458f4026de6d4dba29 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 Jul 2024 21:11:35 -0500 Subject: [PATCH 111/248] Shut up linter --- meshtastic/ble_interface.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index b63635d..4823473 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -2,6 +2,7 @@ """ import asyncio import atexit +import google.protobuf import logging import struct import time @@ -9,16 +10,14 @@ from threading import Thread from typing import List, Optional import print_color # type: ignore[import-untyped] -from .protobuf import ( - mesh_pb2, -) -import google.protobuf - from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError from meshtastic.mesh_interface import MeshInterface +from .protobuf import ( + mesh_pb2, +) SERVICE_UUID = "6ba1b218-15a8-461f-9fa8-5dcae273eafd" TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7" FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002" From 5eafc2c8669807f01360cf91077e9c34544204fb Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 2 Jul 2024 07:30:27 -0500 Subject: [PATCH 112/248] Remove newline handling --- meshtastic/ble_interface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 4823473..eca2204 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -93,7 +93,6 @@ class BLEInterface(MeshInterface): log_record = mesh_pb2.LogRecord() try: log_record.ParseFromString(bytes(b)) - log_record.message = log_record.message.replace("\n", "") except google.protobuf.message.DecodeError: return From 32b4575262bb90f03978fe9bd959e21fe44c0ab2 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 2 Jul 2024 09:43:49 -0700 Subject: [PATCH 113/248] Reorganize imports for pylint --- meshtastic/ble_interface.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index eca2204..bc57157 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -2,7 +2,6 @@ """ import asyncio import atexit -import google.protobuf import logging import struct import time @@ -13,6 +12,8 @@ import print_color # type: ignore[import-untyped] from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError +import google.protobuf + from meshtastic.mesh_interface import MeshInterface from .protobuf import ( From 91c42d598ec1987c9873052891f84b0386abbb4f Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 2 Jul 2024 16:46:09 +0000 Subject: [PATCH 114/248] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 730ca20..e5d9b22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.12" +version = "2.3.13" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From dc5f59260f7a52a14716b5f291a5bda878e5d3bb Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 2 Jul 2024 09:52:47 -0700 Subject: [PATCH 115/248] protobufs: v2.3.14 --- meshtastic/protobuf/config_pb2.py | 62 +++++++++--------- meshtastic/protobuf/config_pb2.pyi | 17 ++++- meshtastic/protobuf/mesh_pb2.py | 12 ++-- meshtastic/protobuf/mesh_pb2.pyi | 8 +++ meshtastic/protobuf/powermon_pb2.py | 28 ++++++++ meshtastic/protobuf/powermon_pb2.pyi | 97 ++++++++++++++++++++++++++++ protobufs | 2 +- 7 files changed, 186 insertions(+), 40 deletions(-) create mode 100644 meshtastic/protobuf/powermon_pb2.py create mode 100644 meshtastic/protobuf/powermon_pb2.pyi diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index 2a18126..7aa80b9 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\x85#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xea\x01\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xbf#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xaa\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x11\n\rROUTER_CLIENT\x10\x03\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xd6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\x1e\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,7 +26,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=4543 + _globals['_CONFIG']._serialized_end=4601 _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 _globals['_CONFIG_DEVICECONFIG']._serialized_end=1172 _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 @@ -40,33 +40,33 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1788 _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1841 _globals['_CONFIG_POWERCONFIG']._serialized_start=1844 - _globals['_CONFIG_POWERCONFIG']._serialized_end=2078 - _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2081 - _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2481 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2374 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2444 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2446 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2481 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2484 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3502 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3048 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3125 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3127 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3167 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3169 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3246 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3248 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3313 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3316 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3502 - _globals['_CONFIG_LORACONFIG']._serialized_start=3505 - _globals['_CONFIG_LORACONFIG']._serialized_end=4339 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=3983 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4188 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4191 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4339 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4342 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4524 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4468 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4524 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2104 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2107 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2507 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2400 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2470 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2472 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2507 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2510 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3528 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3074 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3151 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3153 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3193 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3195 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3272 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3274 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3339 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3342 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3528 + _globals['_CONFIG_LORACONFIG']._serialized_start=3531 + _globals['_CONFIG_LORACONFIG']._serialized_end=4365 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4009 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4214 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4217 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4365 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4368 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4582 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4526 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4582 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 776a627..9da9dc4 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -580,6 +580,7 @@ class Config(google.protobuf.message.Message): LS_SECS_FIELD_NUMBER: builtins.int MIN_WAKE_SECS_FIELD_NUMBER: builtins.int DEVICE_BATTERY_INA_ADDRESS_FIELD_NUMBER: builtins.int + 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. @@ -623,6 +624,11 @@ class Config(google.protobuf.message.Message): """ I2C address of INA_2XX to use for reading device battery voltage """ + powermon_enables: builtins.int + """ + If non-zero, we want powermon log outputs. With the particular (bitfield) sources enabled. + Note: we picked an ID of 32 so that lower more efficient IDs can be used for more frequently used options. + """ def __init__( self, *, @@ -634,8 +640,9 @@ class Config(google.protobuf.message.Message): ls_secs: builtins.int = ..., min_wake_secs: builtins.int = ..., device_battery_ina_address: builtins.int = ..., + powermon_enables: builtins.int = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... + def ClearField(self, field_name: typing.Literal["adc_multiplier_override", b"adc_multiplier_override", "device_battery_ina_address", b"device_battery_ina_address", "is_power_saving", b"is_power_saving", "ls_secs", b"ls_secs", "min_wake_secs", b"min_wake_secs", "on_battery_shutdown_after_secs", b"on_battery_shutdown_after_secs", "powermon_enables", b"powermon_enables", "sds_secs", b"sds_secs", "wait_bluetooth_secs", b"wait_bluetooth_secs"]) -> None: ... @typing.final class NetworkConfig(google.protobuf.message.Message): @@ -1530,6 +1537,7 @@ class Config(google.protobuf.message.Message): ENABLED_FIELD_NUMBER: builtins.int MODE_FIELD_NUMBER: builtins.int FIXED_PIN_FIELD_NUMBER: builtins.int + DEVICE_LOGGING_ENABLED_FIELD_NUMBER: builtins.int enabled: builtins.bool """ Enable Bluetooth on the device @@ -1542,14 +1550,19 @@ class Config(google.protobuf.message.Message): """ Specified PIN for PairingMode.FixedPin """ + device_logging_enabled: builtins.bool + """ + Enables device (serial style logs) over Bluetooth + """ def __init__( self, *, enabled: builtins.bool = ..., mode: global___Config.BluetoothConfig.PairingMode.ValueType = ..., fixed_pin: builtins.int = ..., + device_logging_enabled: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... + def ClearField(self, field_name: typing.Literal["device_logging_enabled", b"device_logging_enabled", "enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... DEVICE_FIELD_NUMBER: builtins.int POSITION_FIELD_NUMBER: builtins.int diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 23d1004..4696a38 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x96\t\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x42\x11\n\x0fpayload_variant\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xab\t\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,11 +32,11 @@ if _descriptor._USE_C_DESCRIPTORS == False: _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' _globals['_HARDWAREMODEL']._serialized_start=5442 - _globals['_HARDWAREMODEL']._serialized_end=6616 - _globals['_CONSTANTS']._serialized_start=6618 - _globals['_CONSTANTS']._serialized_end=6662 - _globals['_CRITICALERRORCODE']._serialized_start=6665 - _globals['_CRITICALERRORCODE']._serialized_end=6903 + _globals['_HARDWAREMODEL']._serialized_end=6637 + _globals['_CONSTANTS']._serialized_start=6639 + _globals['_CONSTANTS']._serialized_end=6683 + _globals['_CRITICALERRORCODE']._serialized_start=6686 + _globals['_CRITICALERRORCODE']._serialized_end=6924 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 6c984e9..7ecf85a 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -125,6 +125,10 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ RAK2560 Solar base station based on RAK4630 """ + HELTEC_HRU_3601: _HardwareModel.ValueType # 23 + """ + Heltec HRU-3601: https://heltec.org/project/hru-3601/ + """ STATION_G1: _HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -412,6 +416,10 @@ RAK2560: HardwareModel.ValueType # 22 """ RAK2560 Solar base station based on RAK4630 """ +HELTEC_HRU_3601: HardwareModel.ValueType # 23 +""" +Heltec HRU-3601: https://heltec.org/project/hru-3601/ +""" STATION_G1: HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station diff --git a/meshtastic/protobuf/powermon_pb2.py b/meshtastic/protobuf/powermon_pb2.py new file mode 100644 index 0000000..4c34474 --- /dev/null +++ b/meshtastic/protobuf/powermon_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/powermon.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/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\x42\x63\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\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 + _globals['_POWERMON_STATE']._serialized_end=284 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/powermon_pb2.pyi b/meshtastic/protobuf/powermon_pb2.pyi new file mode 100644 index 0000000..5519b74 --- /dev/null +++ b/meshtastic/protobuf/powermon_pb2.pyi @@ -0,0 +1,97 @@ +""" +@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 + +@typing.final +class PowerMon(google.protobuf.message.Message): + """Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). + But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _State: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PowerMon._State.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CPU_DeepSleep: PowerMon._State.ValueType # 1 + CPU_LightSleep: PowerMon._State.ValueType # 2 + Vext1_On: PowerMon._State.ValueType # 4 + """ + The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only + occasionally. In cases where that rail has multiple devices on it we usually want to have logging on + the state of that rail as an independent record. + For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. + + The log messages will be short and complete (see PowerMon.Event in the protobufs for details). + something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. + (We use a bitmask for states so that if a log message gets lost it won't be fatal) + """ + Lora_RXOn: PowerMon._State.ValueType # 8 + Lora_TXOn: PowerMon._State.ValueType # 16 + Lora_RXActive: PowerMon._State.ValueType # 32 + BT_On: PowerMon._State.ValueType # 64 + LED_On: PowerMon._State.ValueType # 128 + Screen_On: PowerMon._State.ValueType # 256 + Screen_Drawing: PowerMon._State.ValueType # 512 + Wifi_On: PowerMon._State.ValueType # 1024 + GPS_Active: PowerMon._State.ValueType # 2048 + """ + GPS is actively trying to find our location + See GPSPowerState for more details + """ + + class State(_State, metaclass=_StateEnumTypeWrapper): + """Any significant power changing event in meshtastic should be tagged with a powermon state transition. + If you are making new meshtastic features feel free to add new entries at the end of this definition. + """ + + CPU_DeepSleep: PowerMon.State.ValueType # 1 + CPU_LightSleep: PowerMon.State.ValueType # 2 + Vext1_On: PowerMon.State.ValueType # 4 + """ + The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only + occasionally. In cases where that rail has multiple devices on it we usually want to have logging on + the state of that rail as an independent record. + For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. + + The log messages will be short and complete (see PowerMon.Event in the protobufs for details). + something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. + (We use a bitmask for states so that if a log message gets lost it won't be fatal) + """ + Lora_RXOn: PowerMon.State.ValueType # 8 + Lora_TXOn: PowerMon.State.ValueType # 16 + Lora_RXActive: PowerMon.State.ValueType # 32 + BT_On: PowerMon.State.ValueType # 64 + LED_On: PowerMon.State.ValueType # 128 + Screen_On: PowerMon.State.ValueType # 256 + Screen_Drawing: PowerMon.State.ValueType # 512 + Wifi_On: PowerMon.State.ValueType # 1024 + GPS_Active: PowerMon.State.ValueType # 2048 + """ + GPS is actively trying to find our location + See GPSPowerState for more details + """ + + def __init__( + self, + ) -> None: ... + +global___PowerMon = PowerMon diff --git a/protobufs b/protobufs index 0c90a68..4da558d 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 0c90a6814fdd959a35bb6cf8e958e74d48e8a601 +Subproject commit 4da558d0f73c46ef91b74431facee73c09affbfc From a14cc4f57312153525b6b1063e9c20e6fc3838c7 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 2 Jul 2024 09:58:45 -0700 Subject: [PATCH 116/248] Update heartbeat interval to a fixed 300 seconds --- meshtastic/mesh_interface.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index bf7d715..8753757 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -715,9 +715,8 @@ class MeshInterface: # pylint: disable=R0902 def callback(): self.heartbeatTimer = None - prefs = self.localNode.localConfig - i = prefs.power.ls_secs / 2 - logging.debug(f"Sending heartbeat, interval {i}") + i = 300 + logging.debug(f"Sending heartbeat, interval {i} seconds") if i != 0: self.heartbeatTimer = threading.Timer(i, callback) self.heartbeatTimer.start() From 775108b47bc87fe53369f16941bf48cf74cf56a6 Mon Sep 17 00:00:00 2001 From: Paul Picazo Date: Tue, 2 Jul 2024 10:09:58 -0700 Subject: [PATCH 117/248] Hop limit param on sendTraceRoute fix --- meshtastic/mesh_interface.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index bf7d715..3508a34 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -325,6 +325,7 @@ class MeshInterface: # pylint: disable=R0902 onResponse: Optional[Callable[[dict], Any]]=None, onResponseAckPermitted: bool=False, channelIndex: int=0, + hopLimit: Optional[int]=None, ): """Send a data packet to some other node @@ -347,7 +348,8 @@ class MeshInterface: # pylint: disable=R0902 for regular ACKs (True) or just data responses & NAKs (False) Note that if the onResponse callback is called 'onAckNak' this will implicitly be true. - channelIndex - channel number to use + channelIndex -- channel number to use + hopLimit -- hop limit to use Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. @@ -379,7 +381,7 @@ class MeshInterface: # pylint: disable=R0902 if onResponse is not None: 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) + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit) return p def sendPosition( @@ -478,6 +480,7 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=True, onResponse=self.onResponseTraceRoute, channelIndex=channelIndex, + hopLimit=hopLimit, ) # extend timeout based on number of nodes, limit by configured hopLimit waitFactor = min(len(self.nodes) - 1 if self.nodes else 0, hopLimit) @@ -563,7 +566,7 @@ class MeshInterface: # pylint: disable=R0902 def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any], ackPermitted: bool=False): self.responseHandlers[requestId] = ResponseHandler(callback=callback, ackPermitted=ackPermitted) - def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False): + def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False, hopLimit: Optional[int]=None): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. @@ -604,9 +607,12 @@ class MeshInterface: # pylint: disable=R0902 meshPacket.to = nodeNum meshPacket.want_ack = wantAck - loraConfig = getattr(self.localNode.localConfig, "lora") - hopLimit = getattr(loraConfig, "hop_limit") - meshPacket.hop_limit = hopLimit + + if hopLimit is not None: + meshPacket.hop_limit = hopLimit + else: + loraConfig = getattr(self.localNode.localConfig, "lora") + meshPacket.hop_limit = getattr(loraConfig, "hop_limit") # if the user hasn't set an ID for this packet (likely and recommended), # we should pick a new unique ID so the message can be tracked. From ae2ef78560f21aa8cfe90dd58a9916e07498c614 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 3 Jul 2024 09:53:23 -0700 Subject: [PATCH 118/248] fix linter warnings (note: the linter test for min/max is buggy so disabled) --- .pylintrc | 2 +- meshtastic/__main__.py | 5 ++--- meshtastic/powermon/__init__.py | 2 +- meshtastic/powermon/ppk2.py | 5 +++-- meshtastic/powermon/stress.py | 29 ++++++++++++++++------------- meshtastic/slog/arrow.py | 2 +- meshtastic/slog/slog.py | 3 ++- 7 files changed, 26 insertions(+), 22 deletions(-) diff --git a/.pylintrc b/.pylintrc index 3201e41..c94cddf 100644 --- a/.pylintrc +++ b/.pylintrc @@ -23,7 +23,7 @@ ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_ # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # -disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,pointless-string-statement,too-few-public-methods,broad-except,no-else-return,no-else-raise,bare-except,too-many-public-methods +disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,pointless-string-statement,too-few-public-methods,broad-except,no-else-return,no-else-raise,bare-except,too-many-public-methods,nested-min-max [BASIC] diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3691359..f070849 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -854,7 +854,7 @@ def onConnected(interface): if args.slog_out or args.power_stress: # Setup loggers - global meter + global meter # pylint: disable=global-variable-not-assigned LogSet(interface, args.slog_out if args.slog_out != 'default' else None, meter) if args.power_stress: @@ -1001,9 +1001,8 @@ def export_config(interface): def create_power_meter(): """Setup the power meter.""" - global meter + global meter # pylint: disable=global-statement args = mt_config.args - meter = None # assume no power meter if args.power_riden: meter = RidenPowerSupply(args.power_riden) elif args.power_ppk2_supply or args.power_ppk2_meter: diff --git a/meshtastic/powermon/__init__.py b/meshtastic/powermon/__init__.py index aefc8ae..12826cc 100644 --- a/meshtastic/powermon/__init__.py +++ b/meshtastic/powermon/__init__.py @@ -4,4 +4,4 @@ from .power_supply import PowerError, PowerMeter, PowerSupply from .ppk2 import PPK2PowerSupply from .riden import RidenPowerSupply from .sim import SimPowerSupply -from .stress import PowerStress \ No newline at end of file +from .stress import PowerStress diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 1e2504d..de400b9 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -9,7 +9,6 @@ from ppk2_api import ppk2_api # type: ignore[import-untyped] from .power_supply import PowerError, PowerSupply - class PPK2PowerSupply(PowerSupply): """Interface for talking with the NRF PPK2 high-resolution micro-power supply. Power Profiler Kit II is what you should google to find it for purchase. @@ -130,7 +129,9 @@ class PPK2PowerSupply(PowerSupply): # must be after setting source voltage and before setting mode self.r.start_measuring() # send command to ppk2 - if not s: # min power outpuf of PPK2. If less than this assume we want just meter mode. + if ( + not s + ): # min power outpuf of PPK2. If less than this assume we want just meter mode. self.r.use_ampere_meter() else: self.r.use_source_meter() # set source meter mode diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py index 0ab8d7d..665e58b 100644 --- a/meshtastic/powermon/stress.py +++ b/meshtastic/powermon/stress.py @@ -3,10 +3,7 @@ import logging import time -from pubsub import pub # type: ignore[import-untyped] - -from meshtastic.protobuf import portnums_pb2 -from meshtastic.protobuf.powermon_pb2 import PowerStressMessage +from ..protobuf import ( portnums_pb2, powermon_pb2 ) def onPowerStressResponse(packet, interface): @@ -20,7 +17,7 @@ class PowerStressClient: The client stub for talking to the firmware PowerStress module. """ - def __init__(self, iface, node_id = None): + def __init__(self, iface, node_id=None): """ Create a new PowerStressClient instance. @@ -31,14 +28,18 @@ class PowerStressClient: if not node_id: node_id = iface.myInfo.my_node_num - self.node_id = node_id + self.node_id = node_id # No need to subscribe - because we # pub.subscribe(onGPIOreceive, "meshtastic.receive.powerstress") def sendPowerStress( - self, cmd: PowerStressMessage.Opcode.ValueType, num_seconds: float = 0.0, onResponse=None + self, + cmd: powermon_pb2.PowerStressMessage.Opcode.ValueType, + num_seconds: float = 0.0, + onResponse=None, ): - r = PowerStressMessage() + """Client goo for talking with the device side agent.""" + r = powermon_pb2.PowerStressMessage() r.cmd = cmd r.num_seconds = num_seconds @@ -49,16 +50,16 @@ class PowerStressClient: wantAck=True, wantResponse=True, onResponse=onResponse, - onResponseAckPermitted=True + onResponseAckPermitted=True, ) + class PowerStress: """Walk the UUT through a set of power states so we can capture repeatable power consumption measurements.""" def __init__(self, iface): self.client = PowerStressClient(iface) - def run(self): """Run the power stress test.""" # Send the power stress command @@ -68,11 +69,13 @@ class PowerStress: nonlocal gotAck gotAck = True - logging.info("Starting power stress test, attempting to contact UUT...") - self.client.sendPowerStress(PowerStressMessage.PRINT_INFO, onResponse=onResponse) + logging.info("Starting power stress test, attempting to contact UUT...") + self.client.sendPowerStress( + powermon_pb2.PowerStressMessage.PRINT_INFO, onResponse=onResponse + ) # Wait for the response while not gotAck: time.sleep(0.1) - logging.info("Power stress test complete.") \ No newline at end of file + logging.info("Power stress test complete.") diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index a2d32e6..0833704 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -4,7 +4,7 @@ import logging import os import pyarrow as pa -import pyarrow.feather as feather +from pyarrow import feather chunk_size = 1000 # disk writes are batched based on this number of rows diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 9c6ae6d..d5c1998 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -118,7 +118,8 @@ class StructuredLogger: self.writer.close() f = self.raw_file self.raw_file = None # mark that we are shutting down - f.close() # Close the raw.txt file + if f: + f.close() # Close the raw.txt file def _onLogMessage(self, line: str) -> None: """Handle log messages. From 5695ec7102e1fb9e1ec182a77b4357c34a2b7f27 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 3 Jul 2024 11:00:42 -0700 Subject: [PATCH 119/248] change --slog to use nargs --- meshtastic/__main__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index f070849..87d23cb 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -852,10 +852,10 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) - if args.slog_out or args.power_stress: + if args.slog or args.power_stress: # Setup loggers global meter # pylint: disable=global-variable-not-assigned - LogSet(interface, args.slog_out if args.slog_out != 'default' else None, meter) + LogSet(interface, args.slog if args.slog != 'default' else None, meter) if args.power_stress: stress = PowerStress(interface) @@ -1584,8 +1584,11 @@ def initParser(): ) power_group.add_argument( - "--slog-out", - help="A directory to store structured logging to, or 'default' for automatically selected.", + "--slog", + help="Store structured-logs (slogs) for this run, optionally you can specifiy a destination directory", + nargs="?", + default=None, + const="default" ) group.add_argument( From 63327986b4d4f9f93c0528d8a23db57200dbcf41 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 3 Jul 2024 20:11:59 -0700 Subject: [PATCH 120/248] fix incorrect Vid - thanks @ianmcorvidae for notixing. 0x04b4 is cypress semi but commonly used in Chinese oscopes (like mine). So it was supposed to be a blacklist not a whitelist! --- meshtastic/util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meshtastic/util.py b/meshtastic/util.py index c95aef0..8cb177c 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -25,16 +25,18 @@ from meshtastic.supported_device import supported_devices from meshtastic.version import get_active_version """Some devices such as a seger jlink or st-link we never want to accidentally open + 0483 STMicroelectronics ST-LINK/V2 + 0136 SEGGER J-Link 1915 NordicSemi (PPK2) 0925 Lakeview Research Saleae Logic (logic analyzer) 04b4:602a Cypress Semiconductor Corp. Hantek DSO-6022BL (oscilloscope) """ -blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915, 0x0925]) +blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915, 0x0925, 0x04b4]) """Some devices are highly likely to be meshtastic. 0x239a RAK4631 0x303a Heltec tracker""" -whitelistVids = dict.fromkeys([0x239a, 0x303a, 0x04b4]) +whitelistVids = dict.fromkeys([0x239a, 0x303a]) def quoteBooleans(a_string): From 15b03b704cedb2734b007f12ff60a050863576c9 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 3 Jul 2024 20:35:58 -0700 Subject: [PATCH 121/248] Correctly detect LocalConfig vs. LocalModuleConfig, again. fixes #630 --- meshtastic/node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/node.py b/meshtastic/node.py index 31a5b03..48b9508 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -128,7 +128,7 @@ class Node: print("Requesting current config from remote node (this can take a while).") msgIndex = configType.index - if configType.containing_type.full_name in ("meshtastic.LocalConfig", "LocalConfig"): + if configType.containing_type.name == "LocalConfig": p = admin_pb2.AdminMessage() p.get_config_request = msgIndex self._sendAdmin(p, wantResponse=True, onResponse=onResponse) From b59aee91f260a21bca41cdf60ef2615b21daad28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 02:31:50 +0000 Subject: [PATCH 122/248] Bump certifi from 2024.6.2 to 2024.7.4 Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.6.2 to 2024.7.4. - [Commits](https://github.com/certifi/python-certifi/compare/2024.06.02...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3331326..0695e57 100644 --- a/poetry.lock +++ b/poetry.lock @@ -119,13 +119,13 @@ files = [ [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -1103,6 +1103,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, From 42e069455ec9c960a7fbad44e5b8387ba09760d4 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 12:43:34 -0700 Subject: [PATCH 123/248] transition through power stress states and capture data meshtastic-py3.12kevinh@kdesktop:~/development/meshtastic/meshtastic-python$ cd /home/kevinh/development/meshtastic/meshtastic-python ; /usr/bin/env /home/kevinh/.cache/pypoetry/virtualenvs/meshtastic-l6tP90xw-py3.12/bin/python /home/kevinh/.vscode/extensions/ms-python.debugpy-2024.6.0-linux-x64/bundled/libs/debugpy/adapter/../../debugpy/launcher 52521 -- -m meshtastic --slog --power-ppk2-meter --power-stress --power-voltage 3.3 INFO file:ppk2.py __init__ line:52 Connected to Power Profiler Kit II (PPK2) INFO file:__main__.py create_power_meter line:1022 Setting power supply to 3.3 volts Connected to radio INFO file:slog.py __init__ line:183 Writing slogs to /home/kevinh/.local/share/meshtastic/slogs/20240706-123803 INFO file:stress.py syncPowerStress line:68 Sending power stress command PRINT_INFO INFO file:stress.py run line:105 Running power stress test 48 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command LED_ON INFO file:stress.py run line:105 Running power stress test 80 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command BT_OFF INFO file:stress.py run line:105 Running power stress test 81 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command BT_ON INFO file:stress.py run line:105 Running power stress test 34 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command CPU_FULLON INFO file:stress.py run line:105 Running power stress test 32 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command CPU_IDLE INFO file:stress.py run line:105 Running power stress test 33 for 5.0 seconds INFO file:stress.py syncPowerStress line:68 Sending power stress command CPU_DEEPSLEEP INFO file:stress.py run line:108 Power stress test complete. INFO file:slog.py close line:201 Closing slogs in /home/kevinh/.local/share/meshtastic/slogs/20240706-123803 WARNING file:arrow.py close line:67 Discarding empty file: /home/kevinh/.local/share/meshtastic/slogs/20240706-123803/slog.arrow INFO file:arrow.py close line:70 Compressing log data into /home/kevinh/.local/share/meshtastic/slogs/20240706-123803/power.feather meshtastic-py3.12kevinh@kdesktop:~/development/meshtastic/meshtastic-python$ --- .vscode/launch.json | 2 +- .vscode/settings.json | 1 + meshtastic/__main__.py | 6 +++- meshtastic/powermon/stress.py | 56 ++++++++++++++++++++++++++--------- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9b4dca4..3b82225 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -204,7 +204,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog-out", "default", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog"] + "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3"] }, { "name": "meshtastic test", diff --git a/.vscode/settings.json b/.vscode/settings.json index 8fbd0a0..db434be 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "bitmask", "boardid", + "DEEPSLEEP", "Meshtastic", "milliwatt", "portnums", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 87d23cb..3873e44 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -852,14 +852,16 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) + log_set: Optional[LogSet] = None # we need to keep a reference to the logset so it doesn't get GCed early if args.slog or args.power_stress: # Setup loggers global meter # pylint: disable=global-variable-not-assigned - LogSet(interface, args.slog if args.slog != 'default' else None, meter) + log_set = LogSet(interface, args.slog if args.slog != 'default' else None, meter) if args.power_stress: stress = PowerStress(interface) stress.run() + closeNow = True # exit immediately after stress test if args.listen: closeNow = False @@ -895,6 +897,8 @@ def onConnected(interface): # if the user didn't ask for serial debugging output, we might want to exit after we've done our operation if (not args.seriallog) and closeNow: interface.close() # after running command then exit + if log_set: + log_set.close() except Exception as ex: print(f"Aborting due to: {ex}") diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py index 665e58b..2a07c63 100644 --- a/meshtastic/powermon/stress.py +++ b/meshtastic/powermon/stress.py @@ -3,7 +3,7 @@ import logging import time -from ..protobuf import ( portnums_pb2, powermon_pb2 ) +from ..protobuf import portnums_pb2, powermon_pb2 def onPowerStressResponse(packet, interface): @@ -53,6 +53,32 @@ class PowerStressClient: onResponseAckPermitted=True, ) + def syncPowerStress( + self, + cmd: powermon_pb2.PowerStressMessage.Opcode.ValueType, + num_seconds: float = 0.0, + ): + """Send a power stress command and wait for the ack.""" + gotAck = False + + def onResponse(packet: dict): # pylint: disable=unused-argument + nonlocal gotAck + gotAck = True + + logging.info(f"Sending power stress command {powermon_pb2.PowerStressMessage.Opcode.Name(cmd)}") + self.sendPowerStress(cmd, onResponse=onResponse, num_seconds=num_seconds) + + if num_seconds == 0.0: + # Wait for the response and then continue + while not gotAck: + time.sleep(0.1) + else: + # we wait a little bit longer than the time the UUT would be waiting (to make sure all of its messages are handled first) + time.sleep(num_seconds + 0.2) # completely block our thread for the duration of the test + if not gotAck: + logging.error("Did not receive ack for power stress command!") + + class PowerStress: """Walk the UUT through a set of power states so we can capture repeatable power consumption measurements.""" @@ -63,19 +89,21 @@ class PowerStress: def run(self): """Run the power stress test.""" # Send the power stress command - gotAck = False - def onResponse(packet: dict): # pylint: disable=unused-argument - nonlocal gotAck - gotAck = True + self.client.syncPowerStress(powermon_pb2.PowerStressMessage.PRINT_INFO) - logging.info("Starting power stress test, attempting to contact UUT...") - self.client.sendPowerStress( - powermon_pb2.PowerStressMessage.PRINT_INFO, onResponse=onResponse - ) + num_seconds = 5.0 + states = [ + powermon_pb2.PowerStressMessage.LED_ON, + powermon_pb2.PowerStressMessage.BT_OFF, + powermon_pb2.PowerStressMessage.BT_ON, + powermon_pb2.PowerStressMessage.CPU_FULLON, + powermon_pb2.PowerStressMessage.CPU_IDLE, + powermon_pb2.PowerStressMessage.CPU_DEEPSLEEP, + ] + for s in states: + s_name = powermon_pb2.PowerStressMessage.Opcode.Name(s) + logging.info(f"Running power stress test {s_name} for {num_seconds} seconds") + self.client.syncPowerStress(s, num_seconds) - # Wait for the response - while not gotAck: - time.sleep(0.1) - - logging.info("Power stress test complete.") + logging.info("Power stress test complete.") \ No newline at end of file From 4c02114b750cab795ef4bfbab55cc22b4cbbddaa Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 13:43:19 -0700 Subject: [PATCH 124/248] fix null pointer if closing an interface which was already shutting down --- meshtastic/serial_interface.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/meshtastic/serial_interface.py b/meshtastic/serial_interface.py index 9a8307d..13b1f6e 100644 --- a/meshtastic/serial_interface.py +++ b/meshtastic/serial_interface.py @@ -67,9 +67,10 @@ class SerialInterface(StreamInterface): def close(self): """Close a connection to the device""" - self.stream.flush() - time.sleep(0.1) - self.stream.flush() - time.sleep(0.1) + 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) From 462d9a83dfa26baec0b76d96876b44916ddc53c1 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 15:07:13 -0700 Subject: [PATCH 125/248] Automatically extract and store all known structured-logs --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 6 ++-- meshtastic/powermon/stress.py | 4 ++- meshtastic/slog/arrow.py | 13 ++++++-- meshtastic/slog/slog.py | 58 +++++++++++++++++++++++++---------- 5 files changed, 60 insertions(+), 23 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3b82225..aac37db 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -204,7 +204,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3"] + "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3873e44..1bcfd56 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -897,8 +897,10 @@ def onConnected(interface): # if the user didn't ask for serial debugging output, we might want to exit after we've done our operation if (not args.seriallog) and closeNow: interface.close() # after running command then exit - if log_set: - log_set.close() + + # Close any structured logs after we've done all of our API operations + if log_set: + log_set.close() except Exception as ex: print(f"Aborting due to: {ex}") diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py index 2a07c63..4e82508 100644 --- a/meshtastic/powermon/stress.py +++ b/meshtastic/powermon/stress.py @@ -95,11 +95,13 @@ class PowerStress: num_seconds = 5.0 states = [ powermon_pb2.PowerStressMessage.LED_ON, + powermon_pb2.PowerStressMessage.LED_OFF, powermon_pb2.PowerStressMessage.BT_OFF, powermon_pb2.PowerStressMessage.BT_ON, powermon_pb2.PowerStressMessage.CPU_FULLON, powermon_pb2.PowerStressMessage.CPU_IDLE, - powermon_pb2.PowerStressMessage.CPU_DEEPSLEEP, + # FIXME - can't test deepsleep yet because the ttyACM device disappears. Fix the python code to retry connections + # powermon_pb2.PowerStressMessage.CPU_DEEPSLEEP, ] for s in states: s_name = powermon_pb2.PowerStressMessage.Opcode.Name(s) diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 0833704..be908ce 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -29,13 +29,22 @@ class ArrowWriter: self.writer.close() self.sink.close() + def set_schema(self, schema: pa.Schema): + """Set the schema for the file. + Only needed for datasets where we can't learn it from the first record written. + + schema (pa.Schema): The schema to use. + """ + assert self.schema is None + self.schema = schema + self.writer = pa.ipc.new_stream(self.sink, schema) + def _write(self): """Write the new rows to the file.""" if len(self.new_rows) > 0: if self.schema is None: # only need to look at the first row to learn the schema - self.schema = pa.Table.from_pylist([self.new_rows[0]]).schema - self.writer = pa.ipc.new_stream(self.sink, self.schema) + self.set_schema(pa.Table.from_pylist([self.new_rows[0]]).schema) self.writer.write_batch(pa.RecordBatch.from_pylist(self.new_rows)) self.new_rows = [] diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index d5c1998..91c6350 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -9,10 +9,12 @@ import threading import time from dataclasses import dataclass from datetime import datetime +from functools import reduce from typing import Optional import parse # type: ignore[import-untyped] import platformdirs +import pyarrow as pa from pubsub import pub # type: ignore[import-untyped] from meshtastic.mesh_interface import MeshInterface @@ -26,15 +28,29 @@ class LogDef: """Log definition.""" code: str # i.e. PM or B or whatever... see meshtastic slog documentation + fields: list[tuple[str, pa.DataType]] # A list of field names and their arrow types format: parse.Parser # A format string that can be used to parse the arguments - def __init__(self, code: str, fmt: str) -> None: + def __init__(self, code: str, fields: list[tuple[str, pa.DataType]]) -> None: """Initialize the LogDef object. code (str): The code. format (str): The format. + """ self.code = code + self.fields = fields + + fmt = "" + for idx, f in enumerate(fields): + if idx != 0: + fmt += "," + + # make the format string + suffix = ( + "" if f[1] == pa.string() else ":d" + ) # treat as a string or an int (the only types we have so far) + fmt += "{" + f[0] + suffix + "}" self.format = parse.compile(fmt) @@ -42,8 +58,9 @@ class LogDef: log_defs = { d.code: d for d in [ - LogDef("B", "{boardid:d},{version}"), - LogDef("PM", "{bitmask:d},{reason}"), + LogDef("B", [("board_id", pa.uint32()), ("sw_version", pa.string())]), + LogDef("PM", [("pm_mask", pa.uint64()), ("pm_reason", pa.string())]), + LogDef("PS", [("ps_state", pa.uint64())]), ] } log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") @@ -99,7 +116,15 @@ class StructuredLogger: client (MeshInterface): The MeshInterface object to monitor. """ self.client = client + + # Setup the arrow writer (and its schema) self.writer = FeatherWriter(f"{dir_path}/slog") + all_fields = reduce( + (lambda x, y: x + y), map(lambda x: x.fields, log_defs.values()) + ) + + self.writer.set_schema(pa.schema(all_fields)) + self.raw_file: Optional[ io.TextIOWrapper ] = open( # pylint: disable=consider-using-with @@ -131,21 +156,20 @@ class StructuredLogger: src = m.group(1) args = m.group(2) args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match - logging.debug(f"SLog {src}, reason: {args}") - if src != "PM": - logging.warning(f"Not yet handling structured log {src} (FIXME)") - else: - d = log_defs.get(src) - if d: - r = d.format.parse(args) # get the values with the correct types - if r: - di = r.named - di["time"] = datetime.now() - self.writer.add_row(di) - else: - logging.warning(f"Failed to parse slog {line} with {d.format}") + logging.debug(f"SLog {src}, args: {args}") + + d = log_defs.get(src) + if d: + r = d.format.parse(args) # get the values with the correct types + if r: + di = r.named + di["time"] = datetime.now() + self.writer.add_row(di) else: - logging.warning(f"Unknown Structured Log: {line}") + logging.warning(f"Failed to parse slog {line} with {d.format}") + else: + logging.warning(f"Unknown Structured Log: {line}") + if self.raw_file: self.raw_file.write(line + "\n") # Write the raw log From 1e447cb52aa6a9bbd3cd97839d627316cce40d89 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 15:26:15 -0700 Subject: [PATCH 126/248] also store raw log messages in the slog file. --- .vscode/launch.json | 2 +- meshtastic/slog/slog.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index aac37db..85e35ba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -204,7 +204,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog"] + "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog", "--ble"] }, { "name": "meshtastic test", diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 91c6350..1666055 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -110,7 +110,7 @@ class StructuredLogger: """Sniffs device logs for structured log messages, extracts those into apache arrow format. Also writes the raw log messages to raw.txt""" - def __init__(self, client: MeshInterface, dir_path: str) -> None: + def __init__(self, client: MeshInterface, dir_path: str, include_raw=True) -> None: """Initialize the StructuredLogger object. client (MeshInterface): The MeshInterface object to monitor. @@ -123,6 +123,10 @@ class StructuredLogger: (lambda x, y: x + y), map(lambda x: x.fields, log_defs.values()) ) + self.include_raw = include_raw + if self.include_raw: + all_fields.append(("raw", pa.string())) + self.writer.set_schema(pa.schema(all_fields)) self.raw_file: Optional[ @@ -151,6 +155,9 @@ class StructuredLogger: line (str): the line of log output """ + + di = {} # the dictionary of the fields we found to log + m = log_regex.match(line) if m: src = m.group(1) @@ -163,13 +170,18 @@ class StructuredLogger: r = d.format.parse(args) # get the values with the correct types if r: di = r.named - di["time"] = datetime.now() - self.writer.add_row(di) else: logging.warning(f"Failed to parse slog {line} with {d.format}") else: logging.warning(f"Unknown Structured Log: {line}") + # Store our structured log record + if di or self.include_raw: + di["time"] = datetime.now() + if self.include_raw: + di["raw"] = line + self.writer.add_row(di) + if self.raw_file: self.raw_file.write(line + "\n") # Write the raw log From fb191092fbca893fa7245db28dfe6913a168e733 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 16:27:20 -0700 Subject: [PATCH 127/248] gracefully shutdown when BLE device connect fails --- meshtastic/ble_interface.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 038cee5..7c8aee6 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -53,9 +53,10 @@ class BLEInterface(MeshInterface): self._receiveThread.start() logging.debug("Threads running") + self.client: Optional[BLEClient] = None try: logging.debug(f"BLE connecting to: {address if address else 'any'}") - self.client: Optional[BLEClient] = self.connect(address) + self.client = self.connect(address) logging.debug("BLE connected") except BLEInterface.BLEError as e: self.close() @@ -207,7 +208,6 @@ class BLEInterface(MeshInterface): self.should_read = True def close(self): - atexit.unregister(self._exit_handler) try: MeshInterface.close(self) except Exception as e: @@ -219,6 +219,7 @@ class BLEInterface(MeshInterface): self._receiveThread = None if self.client: + atexit.unregister(self._exit_handler) self.client.disconnect() self.client.close() self.client = None From ecbda74bd63662434308e90a24fd09ba7758ea2e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 6 Jul 2024 16:41:33 -0700 Subject: [PATCH 128/248] make PPK2 power supply monitor work in supply-mode --- .vscode/launch.json | 2 +- meshtastic/__main__.py | 18 ++++++++++++++---- meshtastic/powermon/ppk2.py | 6 ++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 85e35ba..b3d3934 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -204,7 +204,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog", "--power-ppk2-meter", "--power-stress", "--power-voltage", "3.3", "--seriallog", "--ble"] + "args": ["--slog", "--power-ppk2-supply", "--power-stress", "--power-voltage", "3.3", "--seriallog", "--ble"] }, { "name": "meshtastic test", diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 1bcfd56..d9e3517 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1009,24 +1009,34 @@ def create_power_meter(): global meter # pylint: disable=global-statement args = mt_config.args + + # If the user specified a voltage, make sure it is valid + v = 0.0 + if args.power_voltage: + v = float(args.power_voltage) + if v < 0.8 or v > 5.0: + meshtastic.util.our_exit("Voltage must be between 0.8 and 5.0") + if args.power_riden: meter = RidenPowerSupply(args.power_riden) elif args.power_ppk2_supply or args.power_ppk2_meter: meter = PPK2PowerSupply() + assert v > 0, "Voltage must be specified for PPK2" + meter.v = v # PPK2 requires setting voltage before selecting supply mode meter.setIsSupply(args.power_ppk2_supply) elif args.power_sim: meter = SimPowerSupply() - if meter and args.power_voltage: - v = float(args.power_voltage) - if v < 0.5 or v >5.0: - meshtastic.util.our_exit("Voltage must be between 1.0 and 5.0") + if meter and v: 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: + logging.info("Powered-on, waiting for device to boot") + time.sleep(5) def common(): """Shared code for all of our command line wrappers.""" diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index de400b9..1f4d45d 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -118,9 +118,11 @@ class PPK2PowerSupply(PowerSupply): self.measurement_thread.join() # wait for our thread to finish super().close() - def setIsSupply(self, s: bool): + def setIsSupply(self, is_supply: bool): """If in supply mode we will provide power ourself, otherwise we are just an amp meter.""" + assert self.v > 0.8 # We must set a valid voltage before calling this method + self.r.set_source_voltage( int(self.v * 1000) ) # set source voltage in mV BEFORE setting source mode @@ -130,7 +132,7 @@ class PPK2PowerSupply(PowerSupply): self.r.start_measuring() # send command to ppk2 if ( - not s + not is_supply ): # min power outpuf of PPK2. If less than this assume we want just meter mode. self.r.use_ampere_meter() else: From 72e0f2a92b947e56adc21420ef2e857aec83f299 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 13:47:02 -0700 Subject: [PATCH 129/248] Don't silently ingnore malformed protobufs (the \0 in the device side was at fault) --- meshtastic/ble_interface.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 7c8aee6..8d7f47e 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -8,16 +8,14 @@ import time from threading import Thread from typing import List, Optional +import google.protobuf from bleak import BleakClient, BleakScanner, BLEDevice from bleak.exc import BleakDBusError, BleakError -import google.protobuf - from meshtastic.mesh_interface import MeshInterface -from .protobuf import ( - mesh_pb2, -) +from .protobuf import mesh_pb2 + SERVICE_UUID = "6ba1b218-15a8-461f-9fa8-5dcae273eafd" TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7" FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002" @@ -63,7 +61,9 @@ class BLEInterface(MeshInterface): raise e if self.client.has_characteristic(LEGACY_LOGRADIO_UUID): - self.client.start_notify(LEGACY_LOGRADIO_UUID, self.legacy_log_radio_handler) + self.client.start_notify( + LEGACY_LOGRADIO_UUID, self.legacy_log_radio_handler + ) if self.client.has_characteristic(LOGRADIO_UUID): self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler) @@ -94,11 +94,15 @@ class BLEInterface(MeshInterface): log_record = mesh_pb2.LogRecord() try: log_record.ParseFromString(bytes(b)) - except google.protobuf.message.DecodeError: - return - message = f'[{log_record.source}] {log_record.message}' if log_record.source else log_record.message - self._handleLogLine(message) + message = ( + f"[{log_record.source}] {log_record.message}" + if log_record.source + else log_record.message + ) + self._handleLogLine(message) + except google.protobuf.message.DecodeError: + 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", "") @@ -215,7 +219,9 @@ class BLEInterface(MeshInterface): if self._want_receive: self.want_receive = False # Tell the thread we want it to stop - self._receiveThread.join(timeout=2) # If bleak is hung, don't wait for the thread to exit (it is critical we disconnect) + self._receiveThread.join( + timeout=2 + ) # If bleak is hung, don't wait for the thread to exit (it is critical we disconnect) self._receiveThread = None if self.client: From 84b4188211217ce0e21d537b2aa58288237dccde Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 13:47:19 -0700 Subject: [PATCH 130/248] Gracefully cope with exceptions during power-stress test --- meshtastic/powermon/stress.py | 50 ++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/meshtastic/powermon/stress.py b/meshtastic/powermon/stress.py index 4e82508..b416d8a 100644 --- a/meshtastic/powermon/stress.py +++ b/meshtastic/powermon/stress.py @@ -65,7 +65,9 @@ class PowerStressClient: nonlocal gotAck gotAck = True - logging.info(f"Sending power stress command {powermon_pb2.PowerStressMessage.Opcode.Name(cmd)}") + logging.info( + f"Sending power stress command {powermon_pb2.PowerStressMessage.Opcode.Name(cmd)}" + ) self.sendPowerStress(cmd, onResponse=onResponse, num_seconds=num_seconds) if num_seconds == 0.0: @@ -74,12 +76,13 @@ class PowerStressClient: time.sleep(0.1) else: # we wait a little bit longer than the time the UUT would be waiting (to make sure all of its messages are handled first) - time.sleep(num_seconds + 0.2) # completely block our thread for the duration of the test + time.sleep( + num_seconds + 0.2 + ) # completely block our thread for the duration of the test if not gotAck: logging.error("Did not receive ack for power stress command!") - class PowerStress: """Walk the UUT through a set of power states so we can capture repeatable power consumption measurements.""" @@ -88,24 +91,27 @@ class PowerStress: def run(self): """Run the power stress test.""" - # Send the power stress command + try: + self.client.syncPowerStress(powermon_pb2.PowerStressMessage.PRINT_INFO) - self.client.syncPowerStress(powermon_pb2.PowerStressMessage.PRINT_INFO) + num_seconds = 5.0 + states = [ + powermon_pb2.PowerStressMessage.LED_ON, + powermon_pb2.PowerStressMessage.LED_OFF, + powermon_pb2.PowerStressMessage.BT_OFF, + powermon_pb2.PowerStressMessage.BT_ON, + powermon_pb2.PowerStressMessage.CPU_FULLON, + powermon_pb2.PowerStressMessage.CPU_IDLE, + # FIXME - can't test deepsleep yet because the ttyACM device disappears. Fix the python code to retry connections + # powermon_pb2.PowerStressMessage.CPU_DEEPSLEEP, + ] + for s in states: + s_name = powermon_pb2.PowerStressMessage.Opcode.Name(s) + logging.info( + f"Running power stress test {s_name} for {num_seconds} seconds" + ) + self.client.syncPowerStress(s, num_seconds) - num_seconds = 5.0 - states = [ - powermon_pb2.PowerStressMessage.LED_ON, - powermon_pb2.PowerStressMessage.LED_OFF, - powermon_pb2.PowerStressMessage.BT_OFF, - powermon_pb2.PowerStressMessage.BT_ON, - powermon_pb2.PowerStressMessage.CPU_FULLON, - powermon_pb2.PowerStressMessage.CPU_IDLE, - # FIXME - can't test deepsleep yet because the ttyACM device disappears. Fix the python code to retry connections - # powermon_pb2.PowerStressMessage.CPU_DEEPSLEEP, - ] - for s in states: - s_name = powermon_pb2.PowerStressMessage.Opcode.Name(s) - logging.info(f"Running power stress test {s_name} for {num_seconds} seconds") - self.client.syncPowerStress(s, num_seconds) - - logging.info("Power stress test complete.") \ No newline at end of file + logging.info("Power stress test complete.") + except KeyboardInterrupt as e: + logging.warning(f"Power stress interrupted: {e}") From d35423a8161f60b87e9cf333e4d2adc79f30e185 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 14:57:44 -0700 Subject: [PATCH 131/248] strip \n if it was incorrectly added by the device + # Devices should _not_ be including a newline at the end of each log-line str (especially when + # encapsulated as a LogRecord). But to cope with old device loads, we check for that and fix it here: + if line.endswith("\n"): + line = line[:-1] Also: auto reformatting per our trunk formatting rules. --- meshtastic/mesh_interface.py | 227 +++++++++++++++++++++++------------ 1 file changed, 151 insertions(+), 76 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index a7c8b74..42df8ae 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -10,21 +10,14 @@ import threading import time from datetime import datetime from decimal import Decimal - from typing import Any, Callable, Dict, List, Optional, Union import google.protobuf.json_format -from pubsub import pub # type: ignore[import-untyped] -from tabulate import tabulate import print_color # type: ignore[import-untyped] +from pubsub import pub # type: ignore[import-untyped] +from tabulate import tabulate import meshtastic.node - -from meshtastic.protobuf import ( - mesh_pb2, - portnums_pb2, - telemetry_pb2, -) from meshtastic import ( BROADCAST_ADDR, BROADCAST_NUM, @@ -32,18 +25,20 @@ from meshtastic import ( NODELESS_WANT_CONFIG_ID, ResponseHandler, protocols, - publishingThread + publishingThread, ) +from meshtastic.protobuf import mesh_pb2, portnums_pb2, telemetry_pb2 from meshtastic.util import ( Acknowledgment, Timeout, convert_mac_addr, + message_to_json, our_exit, remove_keys_from_dict, stripnl, - message_to_json, ) + def _timeago(delta_secs: int) -> str: """Convert a number of seconds in the past into a short, friendly string e.g. "now", "30 sec ago", "1 hour ago" @@ -67,7 +62,7 @@ def _timeago(delta_secs: int) -> str: return "now" -class MeshInterface: # pylint: disable=R0902 +class MeshInterface: # pylint: disable=R0902 """Interface class for meshtastic devices Properties: @@ -79,11 +74,14 @@ class MeshInterface: # pylint: disable=R0902 class MeshInterfaceError(Exception): """An exception class for general mesh interface errors""" + def __init__(self, message): self.message = message super().__init__(self.message) - def __init__(self, debugOut=None, noProto: bool=False, noNodes: bool=False) -> None: + def __init__( + self, debugOut=None, noProto: bool = False, noNodes: bool = False + ) -> None: """Constructor Keyword Arguments: @@ -93,13 +91,21 @@ class MeshInterface: # pylint: disable=R0902 on startup, just other configuration information. """ self.debugOut = debugOut - self.nodes: Optional[Dict[str,Dict]] = None # FIXME + 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) # We fixup nodenum later - self.myInfo: Optional[mesh_pb2.MyNodeInfo] = None # We don't have device info yet - self.metadata: Optional[mesh_pb2.DeviceMetadata] = None # We don't have device metadata yet - self.responseHandlers: Dict[int,ResponseHandler] = {} # A map from request ID to the handler + self.localNode: meshtastic.node.Node = meshtastic.node.Node( + self, -1 + ) # We fixup nodenum later + self.myInfo: Optional[ + mesh_pb2.MyNodeInfo + ] = None # We don't have device info yet + self.metadata: Optional[ + mesh_pb2.DeviceMetadata + ] = None # We don't have device metadata yet + self.responseHandlers: Dict[ + int, ResponseHandler + ] = {} # A map from request ID to the handler self.failure = ( None # If we've encountered a fatal exception it will be kept here ) @@ -162,6 +168,12 @@ class MeshInterface: # pylint: disable=R0902 def _handleLogLine(self, line: str) -> None: """Handle a line of log output from the device.""" + + # Devices should _not_ be including a newline at the end of each log-line str (especially when + # encapsulated as a LogRecord). But to cope with old device loads, we check for that and fix it here: + if line.endswith("\n"): + line = line[:-1] + pub.sendMessage("meshtastic.log.line", line=line, interface=self) def _handleLogRecord(self, record: mesh_pb2.LogRecord) -> None: @@ -201,7 +213,9 @@ class MeshInterface: # pylint: disable=R0902 print(infos) return infos - def showNodes(self, includeSelf: bool=True, file=sys.stdout) -> str: # pylint: disable=W0613 + def showNodes( + self, includeSelf: bool = True, file=sys.stdout + ) -> str: # pylint: disable=W0613 """Show table summary of nodes in mesh""" def formatFloat(value, precision=2, unit="") -> Optional[str]: @@ -232,7 +246,11 @@ class MeshInterface: # pylint: disable=R0902 continue presumptive_id = f"!{node['num']:08x}" - row = {"N": 0, "User": f"Meshtastic {presumptive_id[-4:]}", "ID": presumptive_id} + row = { + "N": 0, + "User": f"Meshtastic {presumptive_id[-4:]}", + "ID": presumptive_id, + } user = node.get("user") if user: @@ -241,7 +259,7 @@ class MeshInterface: # pylint: disable=R0902 "User": user.get("longName", "N/A"), "AKA": user.get("shortName", "N/A"), "ID": user["id"], - "Hardware": user.get("hwModel", "UNSET") + "Hardware": user.get("hwModel", "UNSET"), } ) @@ -295,7 +313,9 @@ class MeshInterface: # pylint: disable=R0902 print(table) return table - def getNode(self, nodeId: str, requestChannels: bool=True) -> meshtastic.node.Node: + def getNode( + self, nodeId: str, requestChannels: bool = True + ) -> meshtastic.node.Node: """Return a node object which contains device settings and channel info""" if nodeId in (LOCAL_ADDR, BROADCAST_ADDR): return self.localNode @@ -312,11 +332,11 @@ class MeshInterface: # pylint: disable=R0902 def sendText( self, text: str, - destinationId: Union[int, str]=BROADCAST_ADDR, - wantAck: bool=False, - wantResponse: bool=False, - onResponse: Optional[Callable[[dict], Any]]=None, - channelIndex: int=0, + destinationId: Union[int, str] = BROADCAST_ADDR, + wantAck: bool = False, + wantResponse: bool = False, + onResponse: Optional[Callable[[dict], Any]] = None, + channelIndex: int = 0, ): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. @@ -351,13 +371,13 @@ class MeshInterface: # pylint: disable=R0902 def sendData( self, data, - destinationId: Union[int, str]=BROADCAST_ADDR, - portNum: portnums_pb2.PortNum.ValueType=portnums_pb2.PortNum.PRIVATE_APP, - wantAck: bool=False, - wantResponse: bool=False, - onResponse: Optional[Callable[[dict], Any]]=None, - onResponseAckPermitted: bool=False, - channelIndex: int=0, + destinationId: Union[int, str] = BROADCAST_ADDR, + portNum: portnums_pb2.PortNum.ValueType = portnums_pb2.PortNum.PRIVATE_APP, + wantAck: bool = False, + wantResponse: bool = False, + onResponse: Optional[Callable[[dict], Any]] = None, + onResponseAckPermitted: bool = False, + channelIndex: int = 0, ): """Send a data packet to some other node @@ -411,20 +431,22 @@ class MeshInterface: # pylint: disable=R0902 if onResponse is not None: logging.debug(f"Setting a response handler for requestId {meshPacket.id}") - self._addResponseHandler(meshPacket.id, onResponse, ackPermitted=onResponseAckPermitted) + self._addResponseHandler( + meshPacket.id, onResponse, ackPermitted=onResponseAckPermitted + ) p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck) return p def sendPosition( self, - latitude: float=0.0, - longitude: float=0.0, - altitude: int=0, - timeSec: int=0, - destinationId: Union[int, str]=BROADCAST_ADDR, - wantAck: bool=False, - wantResponse: bool=False, - channelIndex: int=0, + latitude: float = 0.0, + longitude: float = 0.0, + altitude: int = 0, + timeSec: int = 0, + destinationId: Union[int, str] = BROADCAST_ADDR, + wantAck: bool = False, + wantResponse: bool = False, + channelIndex: int = 0, ): """ Send a position packet to some other node (normally a broadcast) @@ -475,20 +497,22 @@ class MeshInterface: # pylint: disable=R0902 def onResponsePosition(self, p): """on response for position""" - if p["decoded"]["portnum"] == 'POSITION_APP': + if p["decoded"]["portnum"] == "POSITION_APP": self._acknowledgment.receivedPosition = True position = mesh_pb2.Position() position.ParseFromString(p["decoded"]["payload"]) ret = "Position received: " if position.latitude_i != 0 and position.longitude_i != 0: - ret += f"({position.latitude_i * 10**-7}, {position.longitude_i * 10**-7})" + ret += ( + f"({position.latitude_i * 10**-7}, {position.longitude_i * 10**-7})" + ) else: ret += "(unknown)" if position.altitude != 0: ret += f" {position.altitude}m" - if position.precision_bits not in [0,32]: + if position.precision_bits not in [0, 32]: ret += f" precision:{position.precision_bits}" elif position.precision_bits == 32: ret += " full precision" @@ -497,11 +521,15 @@ class MeshInterface: # pylint: disable=R0902 print(ret) - elif p["decoded"]["portnum"] == 'ROUTING_APP': - if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE': - our_exit("No response from node. At least firmware 2.1.22 is required on the destination node.") + elif p["decoded"]["portnum"] == "ROUTING_APP": + if p["decoded"]["routing"]["errorReason"] == "NO_RESPONSE": + our_exit( + "No response from node. At least firmware 2.1.22 is required on the destination node." + ) - def sendTraceRoute(self, dest: Union[int, str], hopLimit: int, channelIndex: int=0): + def sendTraceRoute( + self, dest: Union[int, str], hopLimit: int, channelIndex: int = 0 + ): """Send the trace route""" r = mesh_pb2.RouteDiscovery() self.sendData( @@ -532,12 +560,19 @@ class MeshInterface: # pylint: disable=R0902 self._acknowledgment.receivedTraceRoute = True - def sendTelemetry(self, destinationId: Union[int,str]=BROADCAST_ADDR, wantResponse: bool=False, channelIndex: int=0): + def sendTelemetry( + self, + destinationId: Union[int, str] = BROADCAST_ADDR, + wantResponse: bool = False, + channelIndex: int = 0, + ): """Send telemetry and optionally ask for a response""" r = telemetry_pb2.Telemetry() if self.nodes is not None: - node = next(n for n in self.nodes.values() if n["num"] == self.localNode.nodeNum) + node = next( + n for n in self.nodes.values() if n["num"] == self.localNode.nodeNum + ) if node is not None: metrics = node.get("deviceMetrics") if metrics: @@ -572,7 +607,7 @@ class MeshInterface: # pylint: disable=R0902 def onResponseTelemetry(self, p: dict): """on response for telemetry""" - if p["decoded"]["portnum"] == 'TELEMETRY_APP': + if p["decoded"]["portnum"] == "TELEMETRY_APP": self._acknowledgment.receivedTelemetry = True telemetry = telemetry_pb2.Telemetry() telemetry.ParseFromString(p["decoded"]["payload"]) @@ -587,16 +622,32 @@ class MeshInterface: # pylint: disable=R0902 f"Total channel utilization: {telemetry.device_metrics.channel_utilization:.2f}%" ) if telemetry.device_metrics.air_util_tx is not None: - print(f"Transmit air utilization: {telemetry.device_metrics.air_util_tx:.2f}%") + print( + f"Transmit air utilization: {telemetry.device_metrics.air_util_tx:.2f}%" + ) - elif p["decoded"]["portnum"] == 'ROUTING_APP': - if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE': - our_exit("No response from node. At least firmware 2.1.22 is required on the destination node.") + elif p["decoded"]["portnum"] == "ROUTING_APP": + if p["decoded"]["routing"]["errorReason"] == "NO_RESPONSE": + our_exit( + "No response from node. At least firmware 2.1.22 is required on the destination node." + ) - def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any], ackPermitted: bool=False): - self.responseHandlers[requestId] = ResponseHandler(callback=callback, ackPermitted=ackPermitted) + def _addResponseHandler( + self, + requestId: int, + callback: Callable[[dict], Any], + ackPermitted: bool = False, + ): + self.responseHandlers[requestId] = ResponseHandler( + callback=callback, ackPermitted=ackPermitted + ) - def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False): + def _sendPacket( + self, + meshPacket: mesh_pb2.MeshPacket, + destinationId: Union[int, str] = BROADCAST_ADDR, + wantAck: bool = False, + ): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. @@ -663,13 +714,17 @@ class MeshInterface: # pylint: disable=R0902 and self.localNode.waitForConfig() ) if not success: - raise MeshInterface.MeshInterfaceError("Timed out waiting for interface config") + raise MeshInterface.MeshInterfaceError( + "Timed out waiting for interface config" + ) def waitForAckNak(self): """Wait for the ack/nak""" success = self._timeout.waitForAckNak(self._acknowledgment) if not success: - raise MeshInterface.MeshInterfaceError("Timed out waiting for an acknowledgment") + raise MeshInterface.MeshInterfaceError( + "Timed out waiting for an acknowledgment" + ) def waitForTraceRoute(self, waitFactor): """Wait for trace route""" @@ -722,7 +777,9 @@ class MeshInterface: # pylint: disable=R0902 and raise an exception""" if not self.noProto: if not self.isConnected.wait(timeout): # timeout after x seconds - raise MeshInterface.MeshInterfaceError("Timed out waiting for connection completion") + raise MeshInterface.MeshInterfaceError( + "Timed out waiting for connection completion" + ) # If we failed while connecting, raise the connection to the client if self.failure: @@ -731,7 +788,9 @@ class MeshInterface: # pylint: disable=R0902 def _generatePacketId(self) -> int: """Get a new unique packet ID""" if self.currentPacketId is None: - raise MeshInterface.MeshInterfaceError("Not connected yet, can not generate packet") + raise MeshInterface.MeshInterfaceError( + "Not connected yet, can not generate packet" + ) else: self.currentPacketId = (self.currentPacketId + 1) & 0xFFFFFFFF return self.currentPacketId @@ -778,7 +837,9 @@ class MeshInterface: # pylint: disable=R0902 self.myInfo = None self.nodes = {} # nodes keyed by ID self.nodesByNum = {} # nodes keyed by nodenum - self._localChannels = [] # empty until we start getting channels pushed from the device (during config) + self._localChannels = ( + [] + ) # empty until we start getting channels pushed from the device (during config) startConfig = mesh_pb2.ToRadio() if self.configId is None or not self.noNodes: @@ -927,7 +988,7 @@ class MeshInterface: # pylint: disable=R0902 logging.debug("Node without position") # no longer necessary since we're mutating directly in nodesByNum via _getOrCreateByNum - #self.nodesByNum[node["num"]] = node + # self.nodesByNum[node["num"]] = node if "user" in node: # Some nodes might not have user/ids assigned yet if "id" in node["user"]: self.nodes[node["user"]["id"]] = node @@ -953,14 +1014,18 @@ class MeshInterface: # pylint: disable=R0902 elif fromRadio.HasField("mqttClientProxyMessage"): publishingThread.queueWork( lambda: pub.sendMessage( - "meshtastic.mqttclientproxymessage", proxymessage=fromRadio.mqttClientProxyMessage, interface=self + "meshtastic.mqttclientproxymessage", + proxymessage=fromRadio.mqttClientProxyMessage, + interface=self, ) ) elif fromRadio.HasField("xmodemPacket"): publishingThread.queueWork( lambda: pub.sendMessage( - "meshtastic.xmodempacket", packet=fromRadio.xmodemPacket, interface=self + "meshtastic.xmodempacket", + packet=fromRadio.xmodemPacket, + interface=self, ) ) @@ -1067,7 +1132,7 @@ class MeshInterface: # pylint: disable=R0902 return BROADCAST_ADDR try: - return self.nodesByNum[num]["user"]["id"] #type: ignore[index] + return self.nodesByNum[num]["user"]["id"] # type: ignore[index] except: logging.debug(f"Node {num} not found for fromId") return None @@ -1075,7 +1140,9 @@ class MeshInterface: # pylint: disable=R0902 def _getOrCreateByNum(self, nodeNum): """Given a nodenum find the NodeInfo in the DB (or create if necessary)""" if nodeNum == BROADCAST_NUM: - raise MeshInterface.MeshInterfaceError("Can not create/find nodenum by the broadcast num") + raise MeshInterface.MeshInterfaceError( + "Can not create/find nodenum by the broadcast num" + ) if nodeNum in self.nodesByNum: return self.nodesByNum[nodeNum] @@ -1087,9 +1154,9 @@ class MeshInterface: # pylint: disable=R0902 "id": presumptive_id, "longName": f"Meshtastic {presumptive_id[-4:]}", "shortName": f"{presumptive_id[-4:]}", - "hwModel": "UNSET" - } - } # Create a minimal node db entry + "hwModel": "UNSET", + }, + } # Create a minimal node db entry self.nodesByNum[nodeNum] = n return n @@ -1198,13 +1265,21 @@ class MeshInterface: # pylint: disable=R0902 # or the handler is set as ackPermitted, but send NAKs and # other, data-containing responses to the handlers routing = decoded.get("routing") - isAck = routing is not None and ("errorReason" not in routing or routing["errorReason"] == "NONE") + isAck = routing is not None and ( + "errorReason" not in routing or routing["errorReason"] == "NONE" + ) # we keep the responseHandler in dict until we actually call it handler = self.responseHandlers.get(requestId, None) if handler is not None: - if (not isAck) or handler.callback.__name__ == "onAckNak" or handler.ackPermitted: + if ( + (not isAck) + or handler.callback.__name__ == "onAckNak" + or handler.ackPermitted + ): handler = self.responseHandlers.pop(requestId, None) - logging.debug(f"Calling response handler for requestId {requestId}") + logging.debug( + f"Calling response handler for requestId {requestId}" + ) handler.callback(asDict) logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") From a6c3e5cba808ab60693fac85dfa7ea13ef7cafc1 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 14:58:30 -0700 Subject: [PATCH 132/248] properly parse all structured log messages --- meshtastic/slog/slog.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 1666055..7cbea09 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -51,7 +51,9 @@ class LogDef: "" if f[1] == pa.string() else ":d" ) # treat as a string or an int (the only types we have so far) fmt += "{" + f[0] + suffix + "}" - self.format = parse.compile(fmt) + self.format = parse.compile( + fmt + ) # We include a catchall matcher at the end - to ignore stuff we don't understand """A dictionary mapping from logdef code to logdef""" @@ -60,7 +62,7 @@ log_defs = { for d in [ LogDef("B", [("board_id", pa.uint32()), ("sw_version", pa.string())]), LogDef("PM", [("pm_mask", pa.uint64()), ("pm_reason", pa.string())]), - LogDef("PS", [("ps_state", pa.uint64())]), + LogDef("PS", [("ps_state", pa.uint32())]), ] } log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") @@ -139,11 +141,14 @@ class StructuredLogger: def listen_glue(line, interface): # pylint: disable=unused-argument self._onLogMessage(line) - self.listener = pub.subscribe(listen_glue, TOPIC_MESHTASTIC_LOG_LINE) + self._listen_glue = ( + listen_glue # we must save this so it doesn't get garbage collected + ) + self._listener = pub.subscribe(listen_glue, TOPIC_MESHTASTIC_LOG_LINE) def close(self) -> None: """Stop logging.""" - pub.unsubscribe(self.listener, TOPIC_MESHTASTIC_LOG_LINE) + pub.unsubscribe(self._listener, TOPIC_MESHTASTIC_LOG_LINE) self.writer.close() f = self.raw_file self.raw_file = None # mark that we are shutting down @@ -162,14 +167,25 @@ class StructuredLogger: if m: src = m.group(1) args = m.group(2) - args += " " # append a space so that if the last arg is an empty str it will still be accepted as a match logging.debug(f"SLog {src}, args: {args}") d = log_defs.get(src) if d: + last_field = d.fields[-1] + last_is_str = last_field[1] == pa.string() + if last_is_str: + args += " " + # append a space so that if the last arg is an empty str + # it will still be accepted as a match for a str + r = d.format.parse(args) # get the values with the correct types if r: di = r.named + if last_is_str: + di[last_field[0]] = di[last_field[0]].strip() # remove the trailing space we added + if di[last_field[0]] == "": + # If the last field is an empty string, remove it + del di[last_field[0]] else: logging.warning(f"Failed to parse slog {line} with {d.format}") else: From 9297732806664da369d0c06701969a44d03d5e56 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 14:59:11 -0700 Subject: [PATCH 133/248] fix possible race with thread shutdown. somehow receiveThread can be null --- meshtastic/ble_interface.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index 8d7f47e..ff4b5dd 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -196,7 +196,7 @@ class BLEInterface(MeshInterface): def _sendToRadioImpl(self, toRadio): b = toRadio.SerializeToString() - if b: + if b and self.client: # we silently ignore writes while we are shutting down logging.debug(f"TORADIO write: {b.hex()}") try: self.client.write_gatt_char( @@ -219,10 +219,11 @@ class BLEInterface(MeshInterface): if self._want_receive: self.want_receive = False # Tell the thread we want it to stop - self._receiveThread.join( - timeout=2 - ) # If bleak is hung, don't wait for the thread to exit (it is critical we disconnect) - self._receiveThread = None + if self._receiveThread: + self._receiveThread.join( + timeout=2 + ) # If bleak is hung, don't wait for the thread to exit (it is critical we disconnect) + self._receiveThread = None if self.client: atexit.unregister(self._exit_handler) From 8c63f4dec64334d0ef1b5b964aeb283025b293df Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 7 Jul 2024 15:17:26 -0700 Subject: [PATCH 134/248] always write using correct schema for the file --- meshtastic/slog/arrow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index be908ce..d656bea 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -46,7 +46,9 @@ class ArrowWriter: # only need to look at the first row to learn the schema self.set_schema(pa.Table.from_pylist([self.new_rows[0]]).schema) - self.writer.write_batch(pa.RecordBatch.from_pylist(self.new_rows)) + self.writer.write_batch( + pa.RecordBatch.from_pylist(self.new_rows, schema=self.schema) + ) self.new_rows = [] def add_row(self, row_dict: dict): From 64bb668251d35909034449ca29699ab64f3320a7 Mon Sep 17 00:00:00 2001 From: Paul Picazo Date: Sun, 7 Jul 2024 20:30:19 -0700 Subject: [PATCH 135/248] Fix line too long --- meshtastic/mesh_interface.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 3508a34..302d41d 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -566,7 +566,13 @@ class MeshInterface: # pylint: disable=R0902 def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any], ackPermitted: bool=False): self.responseHandlers[requestId] = ResponseHandler(callback=callback, ackPermitted=ackPermitted) - def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False, hopLimit: Optional[int]=None): + def _sendPacket( + self, + meshPacket: mesh_pb2.MeshPacket, + destinationId: Union[int,str]=BROADCAST_ADDR, + wantAck: bool=False, + hopLimit: Optional[int]=None + ): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. From ec4e5210017897403c1e27a073c0465812863f02 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 7 Jul 2024 20:49:38 -0700 Subject: [PATCH 136/248] Add a warning about this being the last version supporting python 3.8 --- meshtastic/__main__.py | 3 +++ meshtastic/util.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index c032a36..657cc41 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -811,6 +811,9 @@ def onConnected(interface): f"*** A newer version v{pypi_version} is available!" ' Consider running "pip install --upgrade meshtastic" ***\n' ) + if sys.version_info[0] == 3 and sys.version_info[1] < 9: + print(" *** this version of the CLI is the last that supports python 3.8 ***") + print(" *** please update your python installation ***") else: print("Showing info of remote node is not supported.") print( diff --git a/meshtastic/util.py b/meshtastic/util.py index 3193802..23f648b 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -317,6 +317,9 @@ def support_info(): ) else: print(f" meshtastic: v{the_version}") + if sys.version_info[0] == 3 and sys.version_info[1] < 9: + print(" *** this version of the CLI is the last that supports python 3.8 ***") + print(" *** please update your python installation ***") print(f" Executable: {sys.argv[0]}") print( f" Python: {platform.python_version()} {platform.python_implementation()} {platform.python_compiler()}" From 62cfe2d7fee31d6f66e6de920bf5235d7c2dacf0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 8 Jul 2024 03:52:47 +0000 Subject: [PATCH 137/248] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e5d9b22..b7a4805 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.13" +version = "2.3.14" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 865bb6a497848cfccab01498fd7c05774547e6a0 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 7 Jul 2024 21:00:26 -0700 Subject: [PATCH 138/248] Remove python 3.8 warning. protobufs: v2.3.15 (brought in by merge) --- meshtastic/__main__.py | 3 --- meshtastic/util.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index e3c594a..87d23cb 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -819,9 +819,6 @@ def onConnected(interface): f"*** A newer version v{pypi_version} is available!" ' Consider running "pip install --upgrade meshtastic" ***\n' ) - if sys.version_info[0] == 3 and sys.version_info[1] < 9: - print(" *** this version of the CLI is the last that supports python 3.8 ***") - print(" *** please update your python installation ***") else: print("Showing info of remote node is not supported.") print( diff --git a/meshtastic/util.py b/meshtastic/util.py index 69a319d..8cb177c 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -322,9 +322,6 @@ def support_info(): ) else: print(f" meshtastic: v{the_version}") - if sys.version_info[0] == 3 and sys.version_info[1] < 9: - print(" *** this version of the CLI is the last that supports python 3.8 ***") - print(" *** please update your python installation ***") print(f" Executable: {sys.argv[0]}") print( f" Python: {platform.python_version()} {platform.python_implementation()} {platform.python_compiler()}" From 3c772b5a31bee2170da8816fc73b0f14e99fcde1 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 7 Jul 2024 21:15:29 -0700 Subject: [PATCH 139/248] Attempt adding python 3.12 to CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82d1c99..543db54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: - "3.9" - "3.10" - "3.11" + - "3.12" steps: - uses: actions/checkout@v4 - name: Install Python 3 @@ -58,6 +59,7 @@ jobs: - "3.9" - "3.10" - "3.11" + - "3.12" steps: - uses: actions/checkout@v4 - name: Install Python 3 From 043530afcac7f135927fda2e8efd2595602e5990 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Jul 2024 09:17:52 -0700 Subject: [PATCH 140/248] fix linter warnings --- meshtastic/mesh_interface.py | 2 +- meshtastic/slog/arrow.py | 5 +++-- meshtastic/slog/slog.py | 9 +++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index a51309d..89709da 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -214,7 +214,7 @@ class MeshInterface: # pylint: disable=R0902 return infos def showNodes( - self, includeSelf: bool = True, file=sys.stdout + self, includeSelf: bool = True ) -> str: # pylint: disable=W0613 """Show table summary of nodes in mesh""" diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index d656bea..0a53fe8 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -2,6 +2,7 @@ import logging import os +from typing import Optional import pyarrow as pa from pyarrow import feather @@ -19,8 +20,8 @@ class ArrowWriter: """ self.sink = pa.OSFile(file_name, "wb") # type: ignore self.new_rows: list[dict] = [] - self.schema: pa.Schema | None = None # haven't yet learned the schema - self.writer: pa.RecordBatchFileWriter | None = None + self.schema: Optional[pa.Schema] = None # haven't yet learned the schema + self.writer: Optional[pa.RecordBatchStreamWriter] = None def close(self): """Close the stream and writes the file as needed.""" diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 7cbea09..6452763 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -129,7 +129,10 @@ class StructuredLogger: if self.include_raw: all_fields.append(("raw", pa.string())) - self.writer.set_schema(pa.schema(all_fields)) + # pass in our name->type tuples a pa.fields + self.writer.set_schema( + pa.schema(map(lambda x: pa.field(x[0], x[1]), all_fields)) + ) self.raw_file: Optional[ io.TextIOWrapper @@ -182,7 +185,9 @@ class StructuredLogger: if r: di = r.named if last_is_str: - di[last_field[0]] = di[last_field[0]].strip() # remove the trailing space we added + di[last_field[0]] = di[ + last_field[0] + ].strip() # remove the trailing space we added if di[last_field[0]] == "": # If the last field is an empty string, remove it del di[last_field[0]] From 0bc608d8cf035e8096588454243fc0b30639af26 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Jul 2024 16:43:07 -0700 Subject: [PATCH 141/248] fix analysis imports to import less --- poetry.lock | 580 +++++++++++++++++++++++++------------------------ pyproject.toml | 7 - 2 files changed, 295 insertions(+), 292 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4c4b23d..e67c9f6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -932,53 +932,53 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.53.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, - {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, - {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, - {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, - {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, - {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, - {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, - {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, - {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, - {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, - {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, - {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, - {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, - {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.extras] @@ -1064,13 +1064,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "hypothesis" -version = "6.104.2" +version = "6.105.1" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.104.2-py3-none-any.whl", hash = "sha256:8b52b7e2462e552c75b819495d5cb6251a2b840accc79cf2ce52588004c915d9"}, - {file = "hypothesis-6.104.2.tar.gz", hash = "sha256:6f2a1489bc8fe1c87ffd202707319b66ec46b2bc11faf6e0161e957b8b9b1eab"}, + {file = "hypothesis-6.105.1-py3-none-any.whl", hash = "sha256:d8993472a7bccfc20172e02ba8636bb0067add92d1fa05e95a40bab02c1e8305"}, + {file = "hypothesis-6.105.1.tar.gz", hash = "sha256:d4eedb42193da9507623f4fe27fd38f715ec19ad30ad7c30e3b25594c0b491dc"}, ] [package.dependencies] @@ -1079,10 +1079,10 @@ exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.55)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.59)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.7)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] -crosshair = ["crosshair-tool (>=0.0.55)", "hypothesis-crosshair (>=0.0.4)"] +crosshair = ["crosshair-tool (>=0.0.59)", "hypothesis-crosshair (>=0.0.7)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] @@ -1156,13 +1156,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.29.4" +version = "6.29.5" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, - {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, ] [package.dependencies] @@ -1378,13 +1378,13 @@ files = [ [[package]] name = "jsonschema" -version = "4.22.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] @@ -1399,11 +1399,11 @@ rfc3339-validator = {version = "*", optional = true, markers = "extra == \"forma rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} rpds-py = ">=0.7.1" uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" @@ -1875,40 +1875,40 @@ files = [ [[package]] name = "matplotlib" -version = "3.9.0" +version = "3.9.1" description = "Python plotting package" optional = false python-versions = ">=3.9" files = [ - {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, - {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, - {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, - {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, - {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, - {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, - {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, - {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, - {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, - {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, - {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, + {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, + {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, + {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, + {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, + {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, + {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, + {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, + {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, + {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, ] [package.dependencies] @@ -2313,84 +2313,95 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -2666,23 +2677,23 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyinstaller" -version = "6.8.0" +version = "6.9.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false python-versions = "<3.13,>=3.8" files = [ - {file = "pyinstaller-6.8.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ff6bc2784c1026f8e2f04aa3760cbed41408e108a9d4cf1dd52ee8351a3f6e1"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:39ac424d2ee2457d2ab11a5091436e75a0cccae207d460d180aa1fcbbafdd528"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_i686.whl", hash = "sha256:355832a3acc7de90a255ecacd4b9f9e166a547a79c8905d49f14e3a75c1acdb9"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:6303c7a009f47e6a96ef65aed49f41e36ece8d079b9193ca92fe807403e5fe80"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2b71509468c811968c0b5decb5bbe85b6292ea52d7b1f26313d2aabb673fa9a5"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ff31c5b99e05a4384bbe2071df67ec8b2b347640a375eae9b40218be2f1754c6"}, - {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:000c36b13fe4cd8d0d8c2bc855b1ddcf39867b5adf389e6b5ca45b25fa3e619d"}, - {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:fe0af018d7d5077180e3144ada89a4da5df8d07716eb7e9482834a56dc57a4e8"}, - {file = "pyinstaller-6.8.0-py3-none-win32.whl", hash = "sha256:d257f6645c7334cbd66f38a4fac62c3ad614cc46302b2b5d9f8cc48c563bce0e"}, - {file = "pyinstaller-6.8.0-py3-none-win_amd64.whl", hash = "sha256:81cccfa9b16699b457f4788c5cc119b50f3cd4d0db924955f15c33f2ad27a50d"}, - {file = "pyinstaller-6.8.0-py3-none-win_arm64.whl", hash = "sha256:1c3060a263758cf7f0144ab4c016097b20451b2469d468763414665db1bb743d"}, - {file = "pyinstaller-6.8.0.tar.gz", hash = "sha256:3f4b6520f4423fe19bcc2fd63ab7238851ae2bdcbc98f25bc5d2f97cc62012e9"}, + {file = "pyinstaller-6.9.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ced2e83acf222b936ea94abc5a5cc96588705654b39138af8fb321d9cf2b954"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:f18a3d551834ef8fb7830d48d4cc1527004d0e6b51ded7181e78374ad6111846"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_i686.whl", hash = "sha256:f2fc568de3d6d2a176716a3fc9f20da06d351e8bea5ddd10ecb5659fce3a05b0"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:a0f378f64ad0655d11ade9fde7877e7573fd3d5066231608ce7dfa9040faecdd"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:7bf0c13c5a8560c89540746ae742f4f4b82290e95a6b478374d9f34959fe25d6"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:da994aba14c5686db88796684de265a8665733b4df09b939f7ebdf097d18df72"}, + {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:4e3e50743c091a06e6d01c59bdd6d03967b453ee5384a9e790759be4129db4a4"}, + {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b041be2fe78da47a269604d62c940d68c62f9a3913bdf64af4123f7689d47099"}, + {file = "pyinstaller-6.9.0-py3-none-win32.whl", hash = "sha256:2bf4de17a1c63c0b797b38e13bfb4d03b5ee7c0a68e28b915a7eaacf6b76087f"}, + {file = "pyinstaller-6.9.0-py3-none-win_amd64.whl", hash = "sha256:43709c70b1da8441a730327a8ed362bfcfdc3d42c1bf89f3e2b0a163cc4e7d33"}, + {file = "pyinstaller-6.9.0-py3-none-win_arm64.whl", hash = "sha256:f15c1ef11ed5ceb32447dfbdab687017d6adbef7fc32aa359d584369bfe56eda"}, + {file = "pyinstaller-6.9.0.tar.gz", hash = "sha256:f4a75c552facc2e2a370f1e422b971b5e5cdb4058ff38cea0235aa21fc0b378f"}, ] [package.dependencies] @@ -2691,7 +2702,7 @@ importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} packaging = ">=22.0" pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} -pyinstaller-hooks-contrib = ">=2024.6" +pyinstaller-hooks-contrib = ">=2024.7" pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} setuptools = ">=42.0.0" @@ -3021,7 +3032,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -3253,110 +3263,110 @@ resolved_reference = "27fd58f069a089676dcaaea2ccb8dc8d24e4c6d9" [[package]] name = "rpds-py" -version = "0.18.1" +version = "0.19.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, + {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, + {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, + {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, + {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, + {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, + {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, + {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, + {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, + {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, + {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, + {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, ] [[package]] @@ -3377,18 +3387,18 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "70.1.1" +version = "70.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, - {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, + {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, + {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -3469,13 +3479,13 @@ widechars = ["wcwidth"] [[package]] name = "tenacity" -version = "8.4.2" +version = "8.5.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, - {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, ] [package.extras] @@ -3534,13 +3544,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.5" +version = "0.13.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, - {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, ] [[package]] @@ -4009,4 +4019,4 @@ tunnel = [] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "a6032933510dcce0d89660fb1548219dee51e3373a65cf4addcec1f2b93fbceb" +content-hash = "a8752ba6272252f0fbf8de7b6635dbbbfee7587a9851e4a2050ec0e4f080a6b4" diff --git a/pyproject.toml b/pyproject.toml index d089606..52f3a7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,13 +52,6 @@ optional = true [tool.poetry.group.analysis.dependencies] jupyterlab = "^4.2.2" -mypy = "^1.10.0" -mypy-protobuf = "^3.6.0" -types-protobuf = "^5.26.0.20240422" -types-tabulate = "^0.9.0.20240106" -types-requests = "^2.31.0.20240406" -types-setuptools = "^69.5.0.20240423" -types-pyyaml = "^6.0.12.20240311" matplotlib = "^3.9.0" ipympl = "^0.9.4" ipywidgets = "^8.1.3" From d0db5cae135fe3079708abdbf9c7b4b05b888ce6 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Jul 2024 16:44:27 -0700 Subject: [PATCH 142/248] Store much higher (time) res power readings any time we've just fetched new readings. This allows for better plotting/analysis but still keeping runtime polling low. --- .vscode/launch.json | 2 +- meshtastic/powermon/ppk2.py | 76 ++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b3d3934..5db7737 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -204,7 +204,7 @@ "request": "launch", "module": "meshtastic", "justMyCode": false, - "args": ["--slog", "--power-ppk2-supply", "--power-stress", "--power-voltage", "3.3", "--seriallog", "--ble"] + "args": ["--slog", "--power-ppk2-supply", "--power-stress", "--power-voltage", "3.3", "--ble"] }, { "name": "meshtastic test", diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 1f4d45d..6a70655 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -9,6 +9,7 @@ from ppk2_api import ppk2_api # type: ignore[import-untyped] from .power_supply import PowerError, PowerSupply + class PPK2PowerSupply(PowerSupply): """Interface for talking with the NRF PPK2 high-resolution micro-power supply. Power Profiler Kit II is what you should google to find it for purchase. @@ -35,12 +36,18 @@ class PPK2PowerSupply(PowerSupply): self.current_min = 0 self.current_sum = 0 self.current_num_samples = 0 + self.current_average = 0 # for tracking avera data read length (to determine if we are sleeping efficiently in measurement_loop) self.total_data_len = 0 self.num_data_reads = 0 self.max_data_len = 0 + # Normally we just sleep with a timeout on this condition (polling the power measurement data repeatedly) + # but any time our measurements have been fully consumed (via reset_measurements) we notify() this condition + # to trigger a new reading ASAP. + self.want_measurement = threading.Condition() + self.r = r = ppk2_api.PPK2_API( portName ) # serial port will be different for you @@ -55,52 +62,57 @@ class PPK2PowerSupply(PowerSupply): def measurement_loop(self): """Endless measurement loop will run in a thread.""" while self.measuring: - # always reads 4096 bytes, even if there is no new samples - or possibly the python single thread (because of global interpreter lock) - # is always behind and thefore we are inherently dropping samples semi randomly!!! - read_data = self.r.get_data() - if read_data != b"": - samples, _ = self.r.get_samples(read_data) + with self.want_measurement: + self.want_measurement.wait(0.0001 if self.num_data_reads == 0 else 0.01) + # normally we poll using this timeout, but sometimes + # reset_measurement() will notify us to read immediately - # update invariants - if len(samples) > 0: - if self.current_num_samples == 0: - self.current_min = samples[ - 0 - ] # we need at least one sample to get an initial min - self.current_max = max(self.current_max, max(samples)) - self.current_min = min(self.current_min, min(samples)) - self.current_sum += sum(samples) - self.current_num_samples += len(samples) - # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") + # always reads 4096 bytes, even if there is no new samples - or possibly the python single thread (because of global interpreter lock) + # is always behind and thefore we are inherently dropping samples semi randomly!!! + read_data = self.r.get_data() + if read_data != b"": + samples, _ = self.r.get_samples(read_data) - self.num_data_reads += 1 - self.total_data_len += len(read_data) - self.max_data_len = max(self.max_data_len, len(read_data)) + # update invariants + if len(samples) > 0: + if ( + self.current_num_samples == 0 + ): # First set of new reads, reset min/max + self.current_max = 0 + self.current_min = samples[ + 0 + ] # we need at least one sample to get an initial min + self.current_max = max(self.current_max, max(samples)) + self.current_min = min(self.current_min, min(samples)) + self.current_sum += sum(samples) + self.current_num_samples += len(samples) + # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") - time.sleep(0.01) # FIXME figure out correct sleep duration + self.num_data_reads += 1 + self.total_data_len += len(read_data) + self.max_data_len = max(self.max_data_len, len(read_data)) def get_min_current_mA(self): - """Returns max current in mA (since last call to this method).""" + """Return the min current in mA.""" return self.current_min / 1000 def get_max_current_mA(self): - """Returns max current in mA (since last call to this method).""" + """Return the max current in mA.""" return self.current_max / 1000 def get_average_current_mA(self): - """Returns average current in mA (since last call to this method).""" - if self.current_num_samples == 0: - return 0 - else: - return ( - self.current_sum / self.current_num_samples / 1000 - ) # measurements are in microamperes, divide by 1000 + """Return the average current in mA.""" + if self.current_num_samples != 0: + # If we have new samples, calculate a new average + self.current_average = self.current_sum / self.current_num_samples + + # Even if we don't have new samples, return the last calculated average + # measurements are in microamperes, divide by 1000 + return self.current_average / 1000 def reset_measurements(self): """Reset current measurements.""" # Use the last reading as the new only reading (to ensure we always have a valid current reading) - self.current_max = 0 - self.current_min = 0 self.current_sum = 0 self.current_num_samples = 0 @@ -110,6 +122,8 @@ class PPK2PowerSupply(PowerSupply): self.num_data_reads = 0 self.total_data_len = 0 self.max_data_len = 0 + with self.want_measurement: + self.want_measurement.notify() # notify the measurement loop to read immediately def close(self) -> None: """Close the power meter.""" From 628a4cb9be64364590f24983e71ca4814418f560 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Jul 2024 16:44:56 -0700 Subject: [PATCH 143/248] Always use IDENTICAL timestamps so the power and slog reports can match --- meshtastic/slog/slog.py | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 6452763..7b7dd06 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -82,17 +82,23 @@ class PowerLogger: ) self.thread.start() + def store_current_reading(self, now: datetime | None = None) -> None: + """Store current power measurement.""" + if now is None: + now = datetime.now() + d = { + "time": now, + "average_mW": self.pMeter.get_average_current_mA(), + "max_mW": self.pMeter.get_max_current_mA(), + "min_mW": self.pMeter.get_min_current_mA(), + } + self.pMeter.reset_measurements() + self.writer.add_row(d) + def _logging_thread(self) -> None: """Background thread for logging the current watts reading.""" while self.is_logging: - d = { - "time": datetime.now(), - "average_mW": self.pMeter.get_average_current_mA(), - "max_mW": self.pMeter.get_max_current_mA(), - "min_mW": self.pMeter.get_min_current_mA(), - } - self.pMeter.reset_measurements() - self.writer.add_row(d) + self.store_current_reading() time.sleep(self.interval) def close(self) -> None: @@ -112,12 +118,19 @@ class StructuredLogger: """Sniffs device logs for structured log messages, extracts those into apache arrow format. Also writes the raw log messages to raw.txt""" - def __init__(self, client: MeshInterface, dir_path: str, include_raw=True) -> None: + def __init__( + self, + client: MeshInterface, + dir_path: str, + power_logger: PowerLogger | None = None, + include_raw=True, + ) -> None: """Initialize the StructuredLogger object. client (MeshInterface): The MeshInterface object to monitor. """ self.client = client + self.power_logger = power_logger # Setup the arrow writer (and its schema) self.writer = FeatherWriter(f"{dir_path}/slog") @@ -129,6 +142,9 @@ class StructuredLogger: if self.include_raw: all_fields.append(("raw", pa.string())) + # Use timestamp as the first column + all_fields.insert(0, ("time", pa.timestamp("us"))) + # pass in our name->type tuples a pa.fields self.writer.set_schema( pa.schema(map(lambda x: pa.field(x[0], x[1]), all_fields)) @@ -198,11 +214,16 @@ class StructuredLogger: # Store our structured log record if di or self.include_raw: - di["time"] = datetime.now() + now = datetime.now() + di["time"] = now if self.include_raw: di["raw"] = line self.writer.add_row(di) + # If we have a sibling power logger, make sure we have a power measurement with the EXACT same timestamp + if self.power_logger: + self.power_logger.store_current_reading(now) + if self.raw_file: self.raw_file.write(line + "\n") # Write the raw log @@ -239,15 +260,16 @@ class LogSet: logging.info(f"Writing slogs to {dir_name}") - self.slog_logger: Optional[StructuredLogger] = StructuredLogger( - client, self.dir_name - ) self.power_logger: Optional[PowerLogger] = ( None if not power_meter else PowerLogger(power_meter, f"{self.dir_name}/power") ) + self.slog_logger: Optional[StructuredLogger] = StructuredLogger( + client, self.dir_name, power_logger=self.power_logger + ) + # Store a lambda so we can find it again to unregister self.atexit_handler = lambda: self.close() # pylint: disable=unnecessary-lambda From fd9b691b743547718513169fe769ac3fbd0a095d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 10 Jul 2024 17:29:42 -0700 Subject: [PATCH 144/248] Include uptime_seconds in sendTelemetry and print upon response --- meshtastic/mesh_interface.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index fe620d0..f4e8671 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -556,6 +556,9 @@ class MeshInterface: # pylint: disable=R0902 air_util_tx = metrics.get("airUtilTx") if air_util_tx is not None: r.device_metrics.air_util_tx = air_util_tx + uptime_seconds = metrics.get("uptimeSeconds") + if uptime_seconds is not None: + r.device_metrics.uptime_seconds = uptime_seconds if wantResponse: onResponse = self.onResponseTelemetry @@ -591,6 +594,8 @@ class MeshInterface: # pylint: disable=R0902 ) if telemetry.device_metrics.air_util_tx is not None: print(f"Transmit air utilization: {telemetry.device_metrics.air_util_tx:.2f}%") + if telemetry.device_metrics.uptime_seconds is not None: + print(f"Uptime: {telemetry.device_metrics.uptime_seconds} s") elif p["decoded"]["portnum"] == 'ROUTING_APP': if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE': From 7e007e7e2486e54ec24946eaab507d88dd75f98e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 11:48:53 -0700 Subject: [PATCH 145/248] make ArrowWriter thread safe --- meshtastic/slog/arrow.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 0a53fe8..4bb2e78 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -1,6 +1,7 @@ """Utilities for Apache Arrow serialization.""" import logging +import threading import os from typing import Optional @@ -22,13 +23,15 @@ class ArrowWriter: self.new_rows: list[dict] = [] self.schema: Optional[pa.Schema] = None # haven't yet learned the schema self.writer: Optional[pa.RecordBatchStreamWriter] = None + self._lock = threading.Condition() # Ensure only one thread writes at a time def close(self): """Close the stream and writes the file as needed.""" - self._write() - if self.writer: - self.writer.close() - self.sink.close() + with self._lock: + self._write() + if self.writer: + self.writer.close() + self.sink.close() def set_schema(self, schema: pa.Schema): """Set the schema for the file. @@ -36,9 +39,10 @@ class ArrowWriter: schema (pa.Schema): The schema to use. """ - assert self.schema is None - self.schema = schema - self.writer = pa.ipc.new_stream(self.sink, schema) + with self._lock: + assert self.schema is None + self.schema = schema + self.writer = pa.ipc.new_stream(self.sink, schema) def _write(self): """Write the new rows to the file.""" @@ -56,9 +60,10 @@ class ArrowWriter: """Add a row to the arrow file. We will automatically learn the schema from the first row. But all rows must use that schema. """ - self.new_rows.append(row_dict) - if len(self.new_rows) >= chunk_size: - self._write() + with self._lock: + self.new_rows.append(row_dict) + if len(self.new_rows) >= chunk_size: + self._write() class FeatherWriter(ArrowWriter): From 3c76e19c33d793c85501c9eb9609f33f6ce8339e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 11:49:12 -0700 Subject: [PATCH 146/248] poll for power readings much more rapidly - traces now look great --- meshtastic/powermon/ppk2.py | 2 +- meshtastic/slog/slog.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index 6a70655..a2edb0f 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -63,7 +63,7 @@ class PPK2PowerSupply(PowerSupply): """Endless measurement loop will run in a thread.""" while self.measuring: with self.want_measurement: - self.want_measurement.wait(0.0001 if self.num_data_reads == 0 else 0.01) + self.want_measurement.wait(0.0001 if self.num_data_reads == 0 else 0.001) # normally we poll using this timeout, but sometimes # reset_measurement() will notify us to read immediately diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 7b7dd06..449446e 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -71,7 +71,7 @@ log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") class PowerLogger: """Logs current watts reading periodically using PowerMeter and ArrowWriter.""" - def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.2) -> None: + def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.01) -> None: """Initialize the PowerLogger object.""" self.pMeter = pMeter self.writer = FeatherWriter(file_path) From b464e90368f9b6140128256dd279113461d78062 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 12:19:16 -0700 Subject: [PATCH 147/248] make ppk2 power meter threadsafe --- meshtastic/powermon/ppk2.py | 48 ++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/meshtastic/powermon/ppk2.py b/meshtastic/powermon/ppk2.py index a2edb0f..2eda4a4 100644 --- a/meshtastic/powermon/ppk2.py +++ b/meshtastic/powermon/ppk2.py @@ -46,7 +46,10 @@ class PPK2PowerSupply(PowerSupply): # Normally we just sleep with a timeout on this condition (polling the power measurement data repeatedly) # but any time our measurements have been fully consumed (via reset_measurements) we notify() this condition # to trigger a new reading ASAP. - self.want_measurement = threading.Condition() + self._want_measurement = threading.Condition() + + # To guard against a brief window while updating measured values + self._result_lock = threading.Condition() self.r = r = ppk2_api.PPK2_API( portName @@ -62,8 +65,10 @@ class PPK2PowerSupply(PowerSupply): def measurement_loop(self): """Endless measurement loop will run in a thread.""" while self.measuring: - with self.want_measurement: - self.want_measurement.wait(0.0001 if self.num_data_reads == 0 else 0.001) + with self._want_measurement: + self._want_measurement.wait( + 0.0001 if self.num_data_reads == 0 else 0.001 + ) # normally we poll using this timeout, but sometimes # reset_measurement() will notify us to read immediately @@ -75,17 +80,20 @@ class PPK2PowerSupply(PowerSupply): # update invariants if len(samples) > 0: - if ( - self.current_num_samples == 0 - ): # First set of new reads, reset min/max + if self.current_num_samples == 0: + # First set of new reads, reset min/max self.current_max = 0 - self.current_min = samples[ - 0 - ] # we need at least one sample to get an initial min + self.current_min = samples[0] + # we need at least one sample to get an initial min + + # The following operations could be expensive, so do outside of the lock + # FIXME - change all these lists into numpy arrays to use lots less CPU self.current_max = max(self.current_max, max(samples)) self.current_min = min(self.current_min, min(samples)) - self.current_sum += sum(samples) - self.current_num_samples += len(samples) + latest_sum = sum(samples) + with self._result_lock: + self.current_sum += latest_sum + self.current_num_samples += len(samples) # logging.debug(f"PPK2 data_len={len(read_data)}, sample_len={len(samples)}") self.num_data_reads += 1 @@ -102,13 +110,14 @@ class PPK2PowerSupply(PowerSupply): def get_average_current_mA(self): """Return the average current in mA.""" - if self.current_num_samples != 0: - # If we have new samples, calculate a new average - self.current_average = self.current_sum / self.current_num_samples + with self._result_lock: + if self.current_num_samples != 0: + # If we have new samples, calculate a new average + self.current_average = self.current_sum / self.current_num_samples - # Even if we don't have new samples, return the last calculated average - # measurements are in microamperes, divide by 1000 - return self.current_average / 1000 + # Even if we don't have new samples, return the last calculated average + # measurements are in microamperes, divide by 1000 + return self.current_average / 1000 def reset_measurements(self): """Reset current measurements.""" @@ -122,8 +131,9 @@ class PPK2PowerSupply(PowerSupply): self.num_data_reads = 0 self.total_data_len = 0 self.max_data_len = 0 - with self.want_measurement: - self.want_measurement.notify() # notify the measurement loop to read immediately + + with self._want_measurement: + self._want_measurement.notify() # notify the measurement loop to read immediately def close(self) -> None: """Close the power meter.""" From 4dbf9b94e99d73ab704bfdc84bc1a23f2b8408f0 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 12:27:16 -0700 Subject: [PATCH 148/248] do a new power measurement every 2ms(ish) --- meshtastic/slog/slog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 449446e..f705470 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -71,7 +71,7 @@ log_regex = re.compile(".*S:([0-9A-Za-z]+):(.*)") class PowerLogger: """Logs current watts reading periodically using PowerMeter and ArrowWriter.""" - def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.01) -> None: + def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.002) -> None: """Initialize the PowerLogger object.""" self.pMeter = pMeter self.writer = FeatherWriter(file_path) From 39e03dbad83e8c2a60e9c9e6cb486750e8ccc8b7 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 16:39:05 -0700 Subject: [PATCH 149/248] add beginnings of analysis viewer (and fix poetry extras usage for tunnel) --- .vscode/launch.json | 8 ++ meshtastic/analysis/__main__.py | 137 +++++++++++++++++++++++++++++++ poetry.lock | 141 ++++++++++++++++---------------- pyproject.toml | 6 +- 4 files changed, 220 insertions(+), 72 deletions(-) create mode 100644 meshtastic/analysis/__main__.py diff --git a/.vscode/launch.json b/.vscode/launch.json index 5db7737..e034f14 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -36,6 +36,14 @@ "justMyCode": true, "args": ["--tunnel", "--debug"] }, + { + "name": "meshtastic analysis", + "type": "debugpy", + "request": "launch", + "module": "meshtastic.analysis", + "justMyCode": true, + "args": [""] + }, { "name": "meshtastic set chan", "type": "debugpy", diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py new file mode 100644 index 0000000..1fe8ef7 --- /dev/null +++ b/meshtastic/analysis/__main__.py @@ -0,0 +1,137 @@ +"""Post-run analysis tools for meshtastic.""" + +import logging +import numpy as np +import pandas as pd +import plotly.express as px +import plotly.graph_objects as go +import pyarrow as pa +import pyarrow.feather as feather +from dash import Dash, Input, Output, callback, dash_table, dcc, html + +from .. import mesh_pb2, powermon_pb2 + +# per https://arrow.apache.org/docs/python/pandas.html#reducing-memory-use-in-table-to-pandas +# use this to get nullable int fields treated as ints rather than floats in pandas +dtype_mapping = { + pa.int8(): pd.Int8Dtype(), + pa.int16(): pd.Int16Dtype(), + pa.int32(): pd.Int32Dtype(), + pa.int64(): pd.Int64Dtype(), + pa.uint8(): pd.UInt8Dtype(), + pa.uint16(): pd.UInt16Dtype(), + pa.uint32(): pd.UInt32Dtype(), + pa.uint64(): pd.UInt64Dtype(), + pa.bool_(): pd.BooleanDtype(), + pa.float32(): pd.Float32Dtype(), + pa.float64(): pd.Float64Dtype(), + pa.string(): pd.StringDtype(), +} + +# sdir = '/home/kevinh/.local/share/meshtastic/slogs/20240626-152804' +sdir = "/home/kevinh/.local/share/meshtastic/slogs/latest" +dpwr = feather.read_table(f"{sdir}/power.feather").to_pandas( + types_mapper=dtype_mapping.get +) +dslog = feather.read_table(f"{sdir}/slog.feather").to_pandas( + types_mapper=dtype_mapping.get +) + + +def get_board_info(): + """Get the board information from the slog dataframe. + + tuple: A tuple containing the board ID and software version. + """ + board_info = dslog[dslog["sw_version"].notnull()] + sw_version = board_info.iloc[0]["sw_version"] + board_id = mesh_pb2.HardwareModel.Name(board_info.iloc[0]["board_id"]) + return (board_id, sw_version) + + +pmon_events = dslog[dslog["pm_mask"].notnull()] + + +pm_masks = pd.Series(pmon_events["pm_mask"]).to_numpy() + +# possible to do this with pandas rolling windows if I was smarter? +pm_changes = [(pm_masks[i - 1] ^ x if i != 0 else x) for i, x in enumerate(pm_masks)] +pm_raises = [(pm_masks[i] & x) for i, x in enumerate(pm_changes)] +pm_falls = [(~pm_masks[i] & x if i != 0 else 0) for i, x in enumerate(pm_changes)] + + +def to_pmon_names(arr) -> list[str]: + """Convert the power monitor state numbers to their corresponding names. + """ + + def to_pmon_name(n): + try: + s = powermon_pb2.PowerMon.State.Name(int(n)) + return s if s != "None" else None + except ValueError: + return None + + return [to_pmon_name(x) for x in arr] + + +pd.options.mode.copy_on_write = True +pmon_events["pm_raises"] = to_pmon_names(pm_raises) +pmon_events["pm_falls"] = to_pmon_names(pm_falls) + +pmon_raises = pmon_events[pmon_events["pm_raises"].notnull()] + + +def create_dash(): + """Create a Dash application for visualizing power consumption data.""" + app = Dash() + + def set_legend(f, name): + f["data"][0]["showlegend"] = True + f["data"][0]["name"] = name + return f + + df = dpwr + avg_pwr_lines = px.line(df, x="time", y="average_mW").update_traces( + line_color="red" + ) + set_legend(avg_pwr_lines, "avg power") + max_pwr_points = px.scatter(df, x="time", y="max_mW").update_traces( + marker_color="blue" + ) + set_legend(max_pwr_points, "max power") + min_pwr_points = px.scatter(df, x="time", y="min_mW").update_traces( + marker_color="green" + ) + set_legend(min_pwr_points, "min power") + + pmon = pmon_raises + fake_y = np.full(len(pmon), 10.0) + pmon_points = px.scatter(pmon, x="time", y=fake_y, text="pm_raises") + + # fig = avg_pwr_lines + # fig.add_trace(max_pwr_points) + # don't show minpower because not that interesting: min_pwr_points.data + fig = go.Figure(data=max_pwr_points.data + avg_pwr_lines.data + pmon_points.data) + + fig.update_layout(legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01)) + + # App layout + app.layout = [ + html.Div(children="Early Meshtastic power analysis tool testing..."), + # dash_table.DataTable(data=df.to_dict('records'), page_size=10), + dcc.Graph(figure=fig), + ] + + return app + + +def main(): + """Entry point of the script.""" + app = create_dash() + port = 8051 + logging.info(f"Running Dash visualization webapp on port {port} (publicly accessible)") + app.run_server(debug=True, host='0.0.0.0', port=port) + + +if __name__ == "__main__": + main() diff --git a/poetry.lock b/poetry.lock index e67c9f6..c49ad98 100644 --- a/poetry.lock +++ b/poetry.lock @@ -122,13 +122,13 @@ test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock [[package]] name = "astroid" -version = "3.2.2" +version = "3.2.3" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" files = [ - {file = "astroid-3.2.2-py3-none-any.whl", hash = "sha256:e8a0083b4bb28fcffb6207a3bfc9e5d0a68be951dd7e336d5dcf639c682388c0"}, - {file = "astroid-3.2.2.tar.gz", hash = "sha256:8ead48e31b92b2e217b6c9733a21afafe479d52d6e164dd25fb1a770c7c3cf94"}, + {file = "astroid-3.2.3-py3-none-any.whl", hash = "sha256:3eae9ea67c11c858cdd2c91337d2e816bd019ac897ca07d7b346ac10105fceb3"}, + {file = "astroid-3.2.3.tar.gz", hash = "sha256:7099b5a60985529d8d46858befa103b82d0d05a5a5e8b816b5303ed96075e1d9"}, ] [package.dependencies] @@ -315,7 +315,7 @@ files = [ name = "blinker" version = "1.8.2" description = "Fast, simple object-to-object and broadcast signaling" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, @@ -603,63 +603,63 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.dependencies] @@ -687,7 +687,7 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] name = "dash" version = "2.17.1" description = "A Python framework for building reactive web-apps. Developed by Plotly." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "dash-2.17.1-py3-none-any.whl", hash = "sha256:3eefc9ac67003f93a06bc3e500cae0a6787c48e6c81f6f61514239ae2da414e4"}, @@ -720,7 +720,7 @@ testing = ["beautifulsoup4 (>=4.8.2)", "cryptography", "dash-testing-stub (>=0.0 name = "dash-core-components" version = "2.0.0" description = "Core component suite for Dash" -optional = false +optional = true python-versions = "*" files = [ {file = "dash_core_components-2.0.0-py3-none-any.whl", hash = "sha256:52b8e8cce13b18d0802ee3acbc5e888cb1248a04968f962d63d070400af2e346"}, @@ -731,7 +731,7 @@ files = [ name = "dash-html-components" version = "2.0.0" description = "Vanilla HTML components for Dash" -optional = false +optional = true python-versions = "*" files = [ {file = "dash_html_components-2.0.0-py3-none-any.whl", hash = "sha256:b42cc903713c9706af03b3f2548bda4be7307a7cf89b7d6eae3da872717d1b63"}, @@ -742,7 +742,7 @@ files = [ name = "dash-table" version = "5.0.0" description = "Dash table" -optional = false +optional = true python-versions = "*" files = [ {file = "dash_table-5.0.0-py3-none-any.whl", hash = "sha256:19036fa352bb1c11baf38068ec62d172f0515f73ca3276c79dee49b95ddc16c9"}, @@ -911,7 +911,7 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "flask" version = "3.0.3" description = "A simple framework for building complex web applications." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"}, @@ -1311,7 +1311,7 @@ colors = ["colorama (>=0.4.6)"] name = "itsdangerous" version = "2.2.0" description = "Safely pass data to untrusted environments and back." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, @@ -2428,7 +2428,7 @@ type = ["mypy (>=1.8)"] name = "plotly" version = "5.22.0" description = "An open-source, interactive data visualization library for Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "plotly-5.22.0-py3-none-any.whl", hash = "sha256:68fc1901f098daeb233cc3dd44ec9dc31fb3ca4f4e53189344199c43496ed006"}, @@ -2886,7 +2886,7 @@ cp2110 = ["hidapi"] name = "pytap2" version = "2.3.0" description = "Object-oriented wrapper around the Linux Tun/Tap device" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "pytap2-2.3.0-py3-none-any.whl", hash = "sha256:a1edc287cf25c61f8fa8415fb6b61e50ac119ef5cd758ce15f2105d2c69f24ef"}, @@ -3206,7 +3206,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "retrying" version = "1.3.4" description = "Retrying" -optional = false +optional = true python-versions = "*" files = [ {file = "retrying-1.3.4-py3-none-any.whl", hash = "sha256:8cc4d43cb8e1125e0ff3344e9de678fefd85db3b750b81b2240dc0183af37b35"}, @@ -3481,7 +3481,7 @@ widechars = ["wcwidth"] name = "tenacity" version = "8.5.0" description = "Retry code until it succeeds" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, @@ -3756,7 +3756,7 @@ test = ["websockets"] name = "werkzeug" version = "3.0.3" description = "The comprehensive WSGI web application library." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, @@ -4014,9 +4014,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -tunnel = [] +analysis = ["dash"] +tunnel = ["pytap2"] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "a8752ba6272252f0fbf8de7b6635dbbbfee7587a9851e4a2050ec0e4f080a6b4" +content-hash = "ebe9b93c7e4215f86530f11c1375eff6c955a438310f189cc4e52511dcb29aab" diff --git a/pyproject.toml b/pyproject.toml index 52f3a7f..6b08d23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,8 @@ ppk2-api = "^0.9.2" pyarrow = "^16.1.0" platformdirs = "^4.2.2" print-color = "^0.4.6" +dash = { version = "^2.17.1", optional = true } +pytap2 = { version = "^2.3.0", optional = true } [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" @@ -35,7 +37,6 @@ pytest-cov = "^5.0.0" pdoc3 = "^0.10.0" autopep8 = "^2.1.0" pylint = "^3.2.3" -pytap2 = "^2.3.0" pyinstaller = "^6.8.0" mypy = "^1.10.0" mypy-protobuf = "^3.6.0" @@ -56,14 +57,15 @@ matplotlib = "^3.9.0" ipympl = "^0.9.4" ipywidgets = "^8.1.3" jupyterlab-widgets = "^3.0.11" -dash = "^2.17.1" [tool.poetry.extras] tunnel = ["pytap2"] +analysis = [ "dash" ] [tool.poetry.scripts] meshtastic = "meshtastic.__main__:main" mesh-tunnel = "meshtastic.__main__:tunnelMain [tunnel]" +mesh-analysis = "meshtastic.analysis.__main__:main [analysis]" # "Poe the poet" (optional) provides an easy way of running non python tools inside the poetry virtualenv # if you would like to use it run "pipx install poe" From 66f83835d9eac189f8674859cd1efa8e82f96e0e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 11 Jul 2024 16:56:01 -0700 Subject: [PATCH 150/248] use bootstrap for layout --- meshtastic/analysis/__main__.py | 5 ++++- poetry.lock | 21 +++++++++++++++++++-- pyproject.toml | 7 ++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index 1fe8ef7..7d080b5 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -8,6 +8,7 @@ import plotly.graph_objects as go import pyarrow as pa import pyarrow.feather as feather from dash import Dash, Input, Output, callback, dash_table, dcc, html +import dash_bootstrap_components as dbc from .. import mesh_pb2, powermon_pb2 @@ -83,7 +84,9 @@ pmon_raises = pmon_events[pmon_events["pm_raises"].notnull()] def create_dash(): """Create a Dash application for visualizing power consumption data.""" - app = Dash() + app = Dash( + external_stylesheets=[dbc.themes.BOOTSTRAP] + ) def set_legend(f, name): f["data"][0]["showlegend"] = True diff --git a/poetry.lock b/poetry.lock index c49ad98..4995f5a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -716,6 +716,23 @@ dev = ["PyYAML (>=5.4.1)", "coloredlogs (>=15.0.1)", "fire (>=0.4.0)"] diskcache = ["diskcache (>=5.2.1)", "multiprocess (>=0.70.12)", "psutil (>=5.8.0)"] testing = ["beautifulsoup4 (>=4.8.2)", "cryptography", "dash-testing-stub (>=0.0.2)", "lxml (>=4.6.2)", "multiprocess (>=0.70.12)", "percy (>=2.0.2)", "psutil (>=5.8.0)", "pytest (>=6.0.2)", "requests[security] (>=2.21.0)", "selenium (>=3.141.0,<=4.2.0)", "waitress (>=1.4.4)"] +[[package]] +name = "dash-bootstrap-components" +version = "1.6.0" +description = "Bootstrap themed components for use in Plotly Dash" +optional = true +python-versions = "<4,>=3.8" +files = [ + {file = "dash_bootstrap_components-1.6.0-py3-none-any.whl", hash = "sha256:97f0f47b38363f18863e1b247462229266ce12e1e171cfb34d3c9898e6e5cd1e"}, + {file = "dash_bootstrap_components-1.6.0.tar.gz", hash = "sha256:960a1ec9397574792f49a8241024fa3cecde0f5930c971a3fc81f016cbeb1095"}, +] + +[package.dependencies] +dash = ">=2.0.0" + +[package.extras] +pandas = ["numpy", "pandas"] + [[package]] name = "dash-core-components" version = "2.0.0" @@ -4014,10 +4031,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -analysis = ["dash"] +analysis = ["dash", "dash-bootstrap-components"] tunnel = ["pytap2"] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "ebe9b93c7e4215f86530f11c1375eff6c955a438310f189cc4e52511dcb29aab" +content-hash = "c8a40e0cc2ceeef6297713527b8b878e29b763a3343e0bdfb456995f9303c09e" diff --git a/pyproject.toml b/pyproject.toml index 6b08d23..05cf219 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" readme = "README.md" [tool.poetry.dependencies] -python = "^3.9,<3.13" # 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason +python = "^3.9,<3.13" # 3.9 is needed for pandas, bleak requires a max of 3.13 for some reason pyserial = "^3.5" protobuf = ">=5.26.0" dotmap = "^1.3.30" @@ -29,6 +29,7 @@ platformdirs = "^4.2.2" print-color = "^0.4.6" dash = { version = "^2.17.1", optional = true } pytap2 = { version = "^2.3.0", optional = true } +dash-bootstrap-components = { version = "^1.6.0", optional = true } [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" @@ -47,7 +48,7 @@ types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" pyarrow-stubs = "^10.0.1.7" -# If you are doing power analysis you probably want these extra devtools +# If you are doing power analysis you might want these extra devtools [tool.poetry.group.analysis] optional = true @@ -60,7 +61,7 @@ jupyterlab-widgets = "^3.0.11" [tool.poetry.extras] tunnel = ["pytap2"] -analysis = [ "dash" ] +analysis = ["dash", "dash-bootstrap-components"] [tool.poetry.scripts] meshtastic = "meshtastic.__main__:main" From c8eb202c15230d2a4d057b20ea418bb20fa620e7 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 13:40:29 -0700 Subject: [PATCH 151/248] cleanup and document analysis stuff --- meshtastic/analysis/__main__.py | 126 +++++++++++++++++++------------- 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index 7d080b5..b15b893 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -29,42 +29,16 @@ dtype_mapping = { pa.string(): pd.StringDtype(), } -# sdir = '/home/kevinh/.local/share/meshtastic/slogs/20240626-152804' -sdir = "/home/kevinh/.local/share/meshtastic/slogs/latest" -dpwr = feather.read_table(f"{sdir}/power.feather").to_pandas( - types_mapper=dtype_mapping.get -) -dslog = feather.read_table(f"{sdir}/slog.feather").to_pandas( - types_mapper=dtype_mapping.get -) - - -def get_board_info(): - """Get the board information from the slog dataframe. - - tuple: A tuple containing the board ID and software version. - """ - board_info = dslog[dslog["sw_version"].notnull()] - sw_version = board_info.iloc[0]["sw_version"] - board_id = mesh_pb2.HardwareModel.Name(board_info.iloc[0]["board_id"]) - return (board_id, sw_version) - - -pmon_events = dslog[dslog["pm_mask"].notnull()] - - -pm_masks = pd.Series(pmon_events["pm_mask"]).to_numpy() - -# possible to do this with pandas rolling windows if I was smarter? -pm_changes = [(pm_masks[i - 1] ^ x if i != 0 else x) for i, x in enumerate(pm_masks)] -pm_raises = [(pm_masks[i] & x) for i, x in enumerate(pm_changes)] -pm_falls = [(~pm_masks[i] & x if i != 0 else 0) for i, x in enumerate(pm_changes)] - +# Configure panda options +pd.options.mode.copy_on_write = True def to_pmon_names(arr) -> list[str]: """Convert the power monitor state numbers to their corresponding names. - """ + arr (list): List of power monitor state numbers. + + Returns the List of corresponding power monitor state names. + """ def to_pmon_name(n): try: s = powermon_pb2.PowerMon.State.Name(int(n)) @@ -74,46 +48,97 @@ def to_pmon_names(arr) -> list[str]: return [to_pmon_name(x) for x in arr] +def read_pandas(filepath: str) -> pd.DataFrame: + """Read a feather file and convert it to a pandas DataFrame. -pd.options.mode.copy_on_write = True -pmon_events["pm_raises"] = to_pmon_names(pm_raises) -pmon_events["pm_falls"] = to_pmon_names(pm_falls) + filepath (str): Path to the feather file. -pmon_raises = pmon_events[pmon_events["pm_raises"].notnull()] + Returns the pandas DataFrame. + """ + return feather.read_table(filepath).to_pandas(types_mapper=dtype_mapping.get) +def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: + """Get the power monitor raises from the slog DataFrame. -def create_dash(): - """Create a Dash application for visualizing power consumption data.""" + dslog (pd.DataFrame): The slog DataFrame. + + Returns the DataFrame containing the power monitor raises. + """ + pmon_events = dslog[dslog["pm_mask"].notnull()] + + pm_masks = pd.Series(pmon_events["pm_mask"]).to_numpy() + + # possible to do this with pandas rolling windows if I was smarter? + pm_changes = [(pm_masks[i - 1] ^ x if i != 0 else x) for i, x in enumerate(pm_masks)] + pm_raises = [(pm_masks[i] & x) for i, x in enumerate(pm_changes)] + pm_falls = [(~pm_masks[i] & x if i != 0 else 0) for i, x in enumerate(pm_changes)] + + pmon_events["pm_raises"] = to_pmon_names(pm_raises) + pmon_events["pm_falls"] = to_pmon_names(pm_falls) + + pmon_raises = pmon_events[pmon_events["pm_raises"].notnull()][["time", "pm_raises"]] + pmon_falls = pmon_events[pmon_events["pm_falls"].notnull()] + + def get_endtime(row): + """Find the corresponding fall event.""" + following = pmon_falls[(pmon_falls["pm_falls"] == row["pm_raises"]) & + (pmon_falls["time"] > row["time"])] + return following.iloc[0] if not following.empty else None + + # HMM - setting end_time doesn't work yet - leave off for now + # pmon_raises['end_time'] = pmon_raises.apply(get_endtime, axis=1) + + return pmon_raises + +def get_board_info(dslog: pd.DataFrame) -> tuple: + """Get the board information from the slog DataFrame. + + dslog (pd.DataFrame): The slog DataFrame. + + Returns a tuple containing the board ID and software version. + """ + board_info = dslog[dslog["sw_version"].notnull()] + sw_version = board_info.iloc[0]["sw_version"] + board_id = mesh_pb2.HardwareModel.Name(board_info.iloc[0]["board_id"]) + return (board_id, sw_version) + +def create_dash(slog_path: str) -> Dash: + """Create a Dash application for visualizing power consumption data. + + slog_path (str): Path to the slog directory. + + Returns the Dash application. + """ app = Dash( external_stylesheets=[dbc.themes.BOOTSTRAP] ) + dpwr = read_pandas(f"{slog_path}/power.feather") + dslog = read_pandas(f"{slog_path}/slog.feather") + + pmon_raises = get_pmon_raises(dslog) + def set_legend(f, name): f["data"][0]["showlegend"] = True f["data"][0]["name"] = name return f - df = dpwr - avg_pwr_lines = px.line(df, x="time", y="average_mW").update_traces( + avg_pwr_lines = px.line(dpwr, x="time", y="average_mW").update_traces( line_color="red" ) set_legend(avg_pwr_lines, "avg power") - max_pwr_points = px.scatter(df, x="time", y="max_mW").update_traces( + max_pwr_points = px.scatter(dpwr, x="time", y="max_mW").update_traces( marker_color="blue" ) set_legend(max_pwr_points, "max power") - min_pwr_points = px.scatter(df, x="time", y="min_mW").update_traces( + min_pwr_points = px.scatter(dpwr, x="time", y="min_mW").update_traces( marker_color="green" ) set_legend(min_pwr_points, "min power") - pmon = pmon_raises - fake_y = np.full(len(pmon), 10.0) - pmon_points = px.scatter(pmon, x="time", y=fake_y, text="pm_raises") + fake_y = np.full(len(pmon_raises), 10.0) + pmon_points = px.scatter(pmon_raises, x="time", y=fake_y, text="pm_raises") - # fig = avg_pwr_lines - # fig.add_trace(max_pwr_points) - # don't show minpower because not that interesting: min_pwr_points.data fig = go.Figure(data=max_pwr_points.data + avg_pwr_lines.data + pmon_points.data) fig.update_layout(legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01)) @@ -121,20 +146,17 @@ def create_dash(): # App layout app.layout = [ html.Div(children="Early Meshtastic power analysis tool testing..."), - # dash_table.DataTable(data=df.to_dict('records'), page_size=10), dcc.Graph(figure=fig), ] return app - def main(): """Entry point of the script.""" - app = create_dash() + app = create_dash(slog_path="/home/kevinh/.local/share/meshtastic/slogs/latest") port = 8051 logging.info(f"Running Dash visualization webapp on port {port} (publicly accessible)") app.run_server(debug=True, host='0.0.0.0', port=port) - if __name__ == "__main__": main() From a4715171e47035cca01d9aacc69bb51dfe4c1d99 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 14:41:47 -0700 Subject: [PATCH 152/248] Add basic arg parsing to the meshtastic analysis stuff --- .vscode/launch.json | 4 +- meshtastic/analysis/__main__.py | 88 ++++++++++++++++++++++----------- meshtastic/slog/__init__.py | 2 +- meshtastic/slog/slog.py | 23 ++++++--- 4 files changed, 78 insertions(+), 39 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e034f14..c179060 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -41,8 +41,8 @@ "type": "debugpy", "request": "launch", "module": "meshtastic.analysis", - "justMyCode": true, - "args": [""] + "justMyCode": false, + "args": [] }, { "name": "meshtastic set chan", diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index b15b893..2fcc7bf 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -1,6 +1,9 @@ """Post-run analysis tools for meshtastic.""" +import argparse import logging + +import dash_bootstrap_components as dbc import numpy as np import pandas as pd import plotly.express as px @@ -8,30 +11,14 @@ import plotly.graph_objects as go import pyarrow as pa import pyarrow.feather as feather from dash import Dash, Input, Output, callback, dash_table, dcc, html -import dash_bootstrap_components as dbc from .. import mesh_pb2, powermon_pb2 - -# per https://arrow.apache.org/docs/python/pandas.html#reducing-memory-use-in-table-to-pandas -# use this to get nullable int fields treated as ints rather than floats in pandas -dtype_mapping = { - pa.int8(): pd.Int8Dtype(), - pa.int16(): pd.Int16Dtype(), - pa.int32(): pd.Int32Dtype(), - pa.int64(): pd.Int64Dtype(), - pa.uint8(): pd.UInt8Dtype(), - pa.uint16(): pd.UInt16Dtype(), - pa.uint32(): pd.UInt32Dtype(), - pa.uint64(): pd.UInt64Dtype(), - pa.bool_(): pd.BooleanDtype(), - pa.float32(): pd.Float32Dtype(), - pa.float64(): pd.Float64Dtype(), - pa.string(): pd.StringDtype(), -} +from ..slog import root_dir # Configure panda options pd.options.mode.copy_on_write = True + def to_pmon_names(arr) -> list[str]: """Convert the power monitor state numbers to their corresponding names. @@ -39,6 +26,7 @@ def to_pmon_names(arr) -> list[str]: Returns the List of corresponding power monitor state names. """ + def to_pmon_name(n): try: s = powermon_pb2.PowerMon.State.Name(int(n)) @@ -48,6 +36,7 @@ def to_pmon_names(arr) -> list[str]: return [to_pmon_name(x) for x in arr] + def read_pandas(filepath: str) -> pd.DataFrame: """Read a feather file and convert it to a pandas DataFrame. @@ -55,8 +44,25 @@ def read_pandas(filepath: str) -> pd.DataFrame: Returns the pandas DataFrame. """ + # per https://arrow.apache.org/docs/python/pandas.html#reducing-memory-use-in-table-to-pandas + # use this to get nullable int fields treated as ints rather than floats in pandas + dtype_mapping = { + pa.int8(): pd.Int8Dtype(), + pa.int16(): pd.Int16Dtype(), + pa.int32(): pd.Int32Dtype(), + pa.int64(): pd.Int64Dtype(), + pa.uint8(): pd.UInt8Dtype(), + pa.uint16(): pd.UInt16Dtype(), + pa.uint32(): pd.UInt32Dtype(), + pa.uint64(): pd.UInt64Dtype(), + pa.bool_(): pd.BooleanDtype(), + pa.float32(): pd.Float32Dtype(), + pa.float64(): pd.Float64Dtype(), + pa.string(): pd.StringDtype(), + } return feather.read_table(filepath).to_pandas(types_mapper=dtype_mapping.get) + def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: """Get the power monitor raises from the slog DataFrame. @@ -69,7 +75,9 @@ def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: pm_masks = pd.Series(pmon_events["pm_mask"]).to_numpy() # possible to do this with pandas rolling windows if I was smarter? - pm_changes = [(pm_masks[i - 1] ^ x if i != 0 else x) for i, x in enumerate(pm_masks)] + pm_changes = [ + (pm_masks[i - 1] ^ x if i != 0 else x) for i, x in enumerate(pm_masks) + ] pm_raises = [(pm_masks[i] & x) for i, x in enumerate(pm_changes)] pm_falls = [(~pm_masks[i] & x if i != 0 else 0) for i, x in enumerate(pm_changes)] @@ -81,8 +89,10 @@ def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: def get_endtime(row): """Find the corresponding fall event.""" - following = pmon_falls[(pmon_falls["pm_falls"] == row["pm_raises"]) & - (pmon_falls["time"] > row["time"])] + following = pmon_falls[ + (pmon_falls["pm_falls"] == row["pm_raises"]) + & (pmon_falls["time"] > row["time"]) + ] return following.iloc[0] if not following.empty else None # HMM - setting end_time doesn't work yet - leave off for now @@ -90,6 +100,7 @@ def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: return pmon_raises + def get_board_info(dslog: pd.DataFrame) -> tuple: """Get the board information from the slog DataFrame. @@ -102,6 +113,18 @@ def get_board_info(dslog: pd.DataFrame) -> tuple: board_id = mesh_pb2.HardwareModel.Name(board_info.iloc[0]["board_id"]) return (board_id, sw_version) + +def create_argparser() -> argparse.ArgumentParser: + """Create the argument parser for the script.""" + parser = argparse.ArgumentParser(description="Meshtastic power analysis tools") + group = parser + group.add_argument( + "--slog", + help="Specify the structured-logs directory (defaults to latest log directory)", + ) + return parser + + def create_dash(slog_path: str) -> Dash: """Create a Dash application for visualizing power consumption data. @@ -109,12 +132,15 @@ def create_dash(slog_path: str) -> Dash: Returns the Dash application. """ - app = Dash( - external_stylesheets=[dbc.themes.BOOTSTRAP] - ) + app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP]) - dpwr = read_pandas(f"{slog_path}/power.feather") - dslog = read_pandas(f"{slog_path}/slog.feather") + parser = create_argparser() + args = parser.parse_args() + if not args.slog: + args.slog = f"{root_dir()}/latest" + + dpwr = read_pandas(f"{args.slog}/power.feather") + dslog = read_pandas(f"{args.slog}/slog.feather") pmon_raises = get_pmon_raises(dslog) @@ -145,18 +171,22 @@ def create_dash(slog_path: str) -> Dash: # App layout app.layout = [ - html.Div(children="Early Meshtastic power analysis tool testing..."), + html.Div(children="Meshtastic power analysis tool testing..."), dcc.Graph(figure=fig), ] return app + def main(): """Entry point of the script.""" app = create_dash(slog_path="/home/kevinh/.local/share/meshtastic/slogs/latest") port = 8051 - logging.info(f"Running Dash visualization webapp on port {port} (publicly accessible)") - app.run_server(debug=True, host='0.0.0.0', port=port) + logging.info( + f"Running Dash visualization webapp on port {port} (publicly accessible)" + ) + app.run_server(debug=True, host="0.0.0.0", port=port) + if __name__ == "__main__": main() diff --git a/meshtastic/slog/__init__.py b/meshtastic/slog/__init__.py index acd5d21..5216ded 100644 --- a/meshtastic/slog/__init__.py +++ b/meshtastic/slog/__init__.py @@ -1,3 +1,3 @@ """Structured logging framework (see dev docs for more info).""" -from .slog import LogSet +from .slog import LogSet, root_dir diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index f705470..326bac6 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -23,6 +23,17 @@ from meshtastic.powermon import PowerMeter from .arrow import FeatherWriter +def root_dir() -> str: + """Return the root directory for slog files.""" + + app_name = "meshtastic" + app_author = "meshtastic" + app_dir = platformdirs.user_data_dir(app_name, app_author) + dir_name = f"{app_dir}/slogs" + os.makedirs(dir_name, exist_ok=True) + return dir_name + + @dataclass(init=False) class LogDef: """Log definition.""" @@ -244,17 +255,15 @@ class LogSet: """ if not dir_name: - app_name = "meshtastic" - app_author = "meshtastic" - app_dir = platformdirs.user_data_dir(app_name, app_author) - dir_name = f"{app_dir}/slogs/{datetime.now().strftime('%Y%m%d-%H%M%S')}" + app_dir = root_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 # symlink might fail on some platforms, if it does fail silently - if os.path.exists(f"{app_dir}/slogs/latest"): - os.unlink(f"{app_dir}/slogs/latest") - os.symlink(dir_name, f"{app_dir}/slogs/latest", target_is_directory=True) + 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 From 4906f79be5a737ee22d4bf20a15075489d4daa56 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 15:19:16 -0700 Subject: [PATCH 153/248] fix linter warnings (and alas: reformat __main__.py) main.py's only real change is log_set: Optional[LogSet] = None # type: ignore[annotation-unchecked] Everything else is the automated reformatting to match our trunk formatting rules. --- meshtastic/__main__.py | 188 ++++++++++++++++++++++---------- meshtastic/analysis/__main__.py | 41 ++++--- 2 files changed, 155 insertions(+), 74 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index d9e3517..b7b86a2 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -13,24 +13,30 @@ import sys import time from typing import Optional -import pyqrcode # type: ignore[import-untyped] +import pyqrcode # type: ignore[import-untyped] import yaml from google.protobuf.json_format import MessageToDict -from pubsub import pub # type: ignore[import-untyped] +from pubsub import pub # type: ignore[import-untyped] import meshtastic.test import meshtastic.util -from meshtastic import mt_config -from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 -from meshtastic import remote_hardware, BROADCAST_ADDR -from meshtastic.version import get_active_version +from meshtastic import BROADCAST_ADDR, mt_config, remote_hardware from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.powermon import RidenPowerSupply, PPK2PowerSupply, SimPowerSupply, PowerStress, PowerMeter +from meshtastic.powermon import ( + PowerMeter, + PowerStress, + PPK2PowerSupply, + RidenPowerSupply, + SimPowerSupply, +) +from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 from meshtastic.slog import LogSet +from meshtastic.version import get_active_version meter: Optional[PowerMeter] = None + def onReceive(packet, interface): """Callback invoked when a packet arrives""" args = mt_config.args @@ -66,11 +72,13 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # pylint: disable=W0613 """Callback invoked when we connect/disconnect from a radio""" print(f"Connection changed: {topic.getName()}") + 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) logging.debug(f"ch:{ch}") - return (ch and ch.role != channel_pb2.Channel.Role.DISABLED) + return ch and ch.role != channel_pb2.Channel.Role.DISABLED + def getPref(node, comp_name): """Get a channel or preferences value""" @@ -146,6 +154,7 @@ def splitCompoundName(comp_name): name.append(comp_name) return name + def traverseConfig(config_root, config, interface_config): """Iterate through current config level preferences and either traverse deeper if preference is a dict or set preference""" snake_name = meshtastic.util.camel_to_snake(config_root) @@ -154,14 +163,11 @@ def traverseConfig(config_root, config, interface_config): if isinstance(config[pref], dict): traverseConfig(pref_name, config[pref], interface_config) else: - setPref( - interface_config, - pref_name, - str(config[pref]) - ) + setPref(interface_config, pref_name, str(config[pref])) return True + def setPref(config, comp_name, valStr) -> bool: """Set a channel or preferences value""" @@ -275,7 +281,9 @@ def onConnected(interface): interface.localNode.removeFixedPosition() elif args.setlat or args.setlon or args.setalt: if args.dest != BROADCAST_ADDR: - print("Setting latitude, longitude, and altitude of remote nodes is not supported.") + print( + "Setting latitude, longitude, and altitude of remote nodes is not supported." + ) return closeNow = True @@ -303,10 +311,17 @@ def onConnected(interface): interface.localNode.setFixedPosition(lat, lon, alt) elif not args.no_time: # We normally provide a current time to the mesh when we connect - if interface.localNode.nodeNum in interface.nodesByNum and "position" in interface.nodesByNum[interface.localNode.nodeNum]: + if ( + interface.localNode.nodeNum in interface.nodesByNum + and "position" in interface.nodesByNum[interface.localNode.nodeNum] + ): # send the same position the node already knows, just to update time position = interface.nodesByNum[interface.localNode.nodeNum]["position"] - interface.sendPosition(position.get("latitude", 0.0), position.get("longitude", 0.0), position.get("altitude", 0.0)) + interface.sendPosition( + position.get("latitude", 0.0), + position.get("longitude", 0.0), + position.get("altitude", 0.0), + ) else: interface.sendPosition() @@ -454,7 +469,9 @@ def onConnected(interface): dest = str(args.traceroute) channelIndex = mt_config.channel_index or 0 if checkChannel(interface, channelIndex): - print(f"Sending traceroute request to {dest} on channelIndex:{channelIndex} (this could take a while)") + print( + f"Sending traceroute request to {dest} on channelIndex:{channelIndex} (this could take a while)" + ) interface.sendTraceRoute(dest, hopLimit, channelIndex=channelIndex) if args.request_telemetry: @@ -463,8 +480,14 @@ def onConnected(interface): else: channelIndex = mt_config.channel_index or 0 if checkChannel(interface, channelIndex): - print(f"Sending telemetry request to {args.dest} on channelIndex:{channelIndex} (this could take a while)") - interface.sendTelemetry(destinationId=args.dest, wantResponse=True, channelIndex=channelIndex) + print( + f"Sending telemetry request to {args.dest} on channelIndex:{channelIndex} (this could take a while)" + ) + interface.sendTelemetry( + destinationId=args.dest, + wantResponse=True, + channelIndex=channelIndex, + ) if args.request_position: if args.dest == BROADCAST_ADDR: @@ -472,8 +495,14 @@ def onConnected(interface): else: channelIndex = mt_config.channel_index or 0 if checkChannel(interface, channelIndex): - print(f"Sending position request to {args.dest} on channelIndex:{channelIndex} (this could take a while)") - interface.sendPosition(destinationId=args.dest, wantResponse=True, channelIndex=channelIndex) + print( + f"Sending position request to {args.dest} on channelIndex:{channelIndex} (this could take a while)" + ) + interface.sendPosition( + destinationId=args.dest, + wantResponse=True, + channelIndex=channelIndex, + ) if args.gpio_wrb or args.gpio_rd or args.gpio_watch: if args.dest == BROADCAST_ADDR: @@ -615,7 +644,9 @@ def onConnected(interface): if "config" in configuration: localConfig = interface.getNode(args.dest).localConfig for section in configuration["config"]: - traverseConfig(section, configuration["config"][section], localConfig) + traverseConfig( + section, configuration["config"][section], localConfig + ) interface.getNode(args.dest).writeConfig( meshtastic.util.camel_to_snake(section) ) @@ -623,7 +654,11 @@ def onConnected(interface): if "module_config" in configuration: moduleConfig = interface.getNode(args.dest).moduleConfig for section in configuration["module_config"]: - traverseConfig(section, configuration["module_config"][section], moduleConfig) + traverseConfig( + section, + configuration["module_config"][section], + moduleConfig, + ) interface.getNode(args.dest).writeConfig( meshtastic.util.camel_to_snake(section) ) @@ -676,7 +711,9 @@ def onConnected(interface): print(f"Writing modified channels to device") n.writeChannel(ch.index) if channelIndex is None: - print(f"Setting newly-added channel's {ch.index} as '--ch-index' for further modifications") + print( + f"Setting newly-added channel's {ch.index} as '--ch-index' for further modifications" + ) mt_config.channel_index = ch.index if args.ch_del: @@ -762,7 +799,7 @@ def onConnected(interface): else: found = setPref(ch.settings, pref[0], pref[1]) if not found: - category_settings = ['module_settings'] + category_settings = ["module_settings"] print( f"{ch.settings.__class__.__name__} does not have an attribute {pref[0]}." ) @@ -772,7 +809,9 @@ def onConnected(interface): print(f"{field.name}") else: print(f"{field.name}:") - config = ch.settings.DESCRIPTOR.fields_by_name.get(field.name) + config = ch.settings.DESCRIPTOR.fields_by_name.get( + field.name + ) names = [] for sub_field in config.message_type.fields: tmp_name = f"{field.name}.{sub_field.name}" @@ -852,16 +891,20 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) - log_set: Optional[LogSet] = None # we need to keep a reference to the logset so it doesn't get GCed early + log_set: Optional[LogSet] = None # type: ignore[annotation-unchecked] + # we need to keep a reference to the logset so it doesn't get GCed early + if args.slog or args.power_stress: # Setup loggers global meter # pylint: disable=global-variable-not-assigned - log_set = LogSet(interface, args.slog if args.slog != 'default' else None, meter) + log_set = LogSet( + interface, args.slog if args.slog != "default" else None, meter + ) if args.power_stress: stress = PowerStress(interface) stress.run() - closeNow = True # exit immediately after stress test + closeNow = True # exit immediately after stress test if args.listen: closeNow = False @@ -891,7 +934,7 @@ def onConnected(interface): interface.getNode(args.dest, False).iface.waitForAckNak() if args.wait_to_disconnect: - print(f"Waiting {args.wait_to_disconnect} seconds before disconnecting" ) + print(f"Waiting {args.wait_to_disconnect} seconds before disconnecting") time.sleep(int(args.wait_to_disconnect)) # if the user didn't ask for serial debugging output, we might want to exit after we've done our operation @@ -1004,6 +1047,7 @@ def export_config(interface): print(config) return config + def create_power_meter(): """Setup the power meter.""" @@ -1038,6 +1082,7 @@ def create_power_meter(): logging.info("Powered-on, waiting for device to boot") time.sleep(5) + def common(): """Shared code for all of our command line wrappers.""" logfile = None @@ -1104,20 +1149,29 @@ def common(): print(f"Found: name='{x.name}' address='{x.address}'") meshtastic.util.our_exit("BLE scan finished", 0) elif args.ble: - client = BLEInterface(args.ble if args.ble != "any" else None, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes) + client = BLEInterface( + args.ble if args.ble != "any" else None, + debugOut=logfile, + noProto=args.noproto, + noNodes=args.no_nodes, + ) elif args.host: try: client = meshtastic.tcp_interface.TCPInterface( - args.host, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes + args.host, + debugOut=logfile, + noProto=args.noproto, + noNodes=args.no_nodes, ) except Exception as ex: - meshtastic.util.our_exit( - f"Error connecting to {args.host}:{ex}", 1 - ) + meshtastic.util.our_exit(f"Error connecting to {args.host}:{ex}", 1) else: try: client = meshtastic.serial_interface.SerialInterface( - args.port, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes + args.port, + debugOut=logfile, + noProto=args.noproto, + noNodes=args.no_nodes, ) except PermissionError as ex: username = os.getlogin() @@ -1132,7 +1186,10 @@ def common(): if client.devPath is None: try: client = meshtastic.tcp_interface.TCPInterface( - "localhost", debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes + "localhost", + debugOut=logfile, + noProto=args.noproto, + noNodes=args.no_nodes, ) except Exception as ex: meshtastic.util.our_exit( @@ -1144,7 +1201,10 @@ def common(): have_tunnel = platform.system() == "Linux" if ( - args.noproto or args.reply or (have_tunnel and args.tunnel) or args.listen + args.noproto + or args.reply + or (have_tunnel and args.tunnel) + or args.listen ): # loop until someone presses ctrlc try: while True: @@ -1155,13 +1215,19 @@ def common(): # don't call exit, background threads might be running still # sys.exit(0) + def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: """Add connection specifiation arguments""" - outer = parser.add_argument_group('Connection', 'Optional arguments that specify how to connect to a Meshtastic device.') + outer = parser.add_argument_group( + "Connection", + "Optional arguments that specify how to connect to a Meshtastic device.", + ) group = outer.add_mutually_exclusive_group() group.add_argument( - "--port", "--serial", "-s", + "--port", + "--serial", + "-s", help="The port of the device to connect to using serial, e.g. /dev/ttyUSB0. (defaults to trying to detect a port)", nargs="?", const=None, @@ -1169,19 +1235,22 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse ) group.add_argument( - "--host", "--tcp", "-t", + "--host", + "--tcp", + "-t", help="Connect to a device using TCP, optionally passing hostname or IP address to use. (defaults to '%(const)s')", nargs="?", default=None, - const="localhost" + const="localhost", ) group.add_argument( - "--ble", "-b", + "--ble", + "-b", help="Connect to a BLE device, optionally specifying a device name (defaults to '%(const)s')", nargs="?", default=None, - const="any" + const="any", ) return parser @@ -1193,9 +1262,11 @@ def initParser(): args = mt_config.args # The "Help" group includes the help option and other informational stuff about the CLI itself - outerHelpGroup = parser.add_argument_group('Help') + outerHelpGroup = parser.add_argument_group("Help") helpGroup = outerHelpGroup.add_mutually_exclusive_group() - helpGroup.add_argument("-h", "--help", action="help", help="show this help message and exit") + helpGroup.add_argument( + "-h", "--help", action="help", help="show this help message and exit" + ) the_version = get_active_version() helpGroup.add_argument("--version", action="version", version=f"{the_version}") @@ -1232,9 +1303,9 @@ def initParser(): group.add_argument( "--seriallog", help="Log device serial output to either 'none' or a filename to append to. Defaults to 'stdout' if no filename specified.", - nargs='?', + nargs="?", const="stdout", - default=None + default=None, ) group.add_argument( @@ -1490,7 +1561,7 @@ def initParser(): group.add_argument( "--remove-node", - help="Tell the destination node to remove a specific node from its DB, by node number or ID" + help="Tell the destination node to remove a specific node from its DB, by node number or ID", ) group.add_argument( "--reset-nodedb", @@ -1555,7 +1626,9 @@ def initParser(): action="store_true", ) - power_group = parser.add_argument_group('Power Testing', 'Options for power testing/logging.') + power_group = parser.add_argument_group( + "Power Testing", "Options for power testing/logging." + ) power_supply_group = power_group.add_mutually_exclusive_group() @@ -1604,7 +1677,7 @@ def initParser(): help="Store structured-logs (slogs) for this run, optionally you can specifiy a destination directory", nargs="?", default=None, - const="default" + const="default", ) group.add_argument( @@ -1633,7 +1706,9 @@ def initParser(): action="store_true", ) - remoteHardwareArgs = parser.add_argument_group('Remote Hardware', 'Arguments related to the Remote Hardware module') + remoteHardwareArgs = parser.add_argument_group( + "Remote Hardware", "Arguments related to the Remote Hardware module" + ) remoteHardwareArgs.add_argument( "--gpio-wrb", nargs=2, help="Set a particular GPIO # to 1 or 0", action="append" @@ -1647,10 +1722,11 @@ def initParser(): "--gpio-watch", help="Start watching a GPIO mask for changes (ex: '0x10')" ) - have_tunnel = platform.system() == "Linux" if have_tunnel: - tunnelArgs = parser.add_argument_group('Tunnel', 'Arguments related to establishing a tunnel device over the mesh.') + tunnelArgs = parser.add_argument_group( + "Tunnel", "Arguments related to establishing a tunnel device over the mesh." + ) tunnelArgs.add_argument( "--tunnel", action="store_true", @@ -1665,7 +1741,6 @@ def initParser(): parser.set_defaults(deprecated=None) - args = parser.parse_args() mt_config.args = args mt_config.parser = parser @@ -1676,7 +1751,8 @@ def main(): parser = argparse.ArgumentParser( add_help=False, epilog="If no connection arguments are specified, we search for a compatible serial device, " - "and if none is found, then attempt a TCP connection to localhost.") + "and if none is found, then attempt a TCP connection to localhost.", + ) mt_config.parser = parser initParser() common() diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index 2fcc7bf..993f04b 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -2,15 +2,16 @@ import argparse import logging +from typing import cast -import dash_bootstrap_components as dbc +import dash_bootstrap_components as dbc # type: ignore[import-untyped] import numpy as np import pandas as pd -import plotly.express as px -import plotly.graph_objects as go +import plotly.express as px # type: ignore[import-untyped] +import plotly.graph_objects as go # type: ignore[import-untyped] import pyarrow as pa -import pyarrow.feather as feather -from dash import Dash, Input, Output, callback, dash_table, dcc, html +from dash import Dash, dcc, html # type: ignore[import-untyped] +from pyarrow import feather from .. import mesh_pb2, powermon_pb2 from ..slog import root_dir @@ -60,7 +61,8 @@ def read_pandas(filepath: str) -> pd.DataFrame: pa.float64(): pd.Float64Dtype(), pa.string(): pd.StringDtype(), } - return feather.read_table(filepath).to_pandas(types_mapper=dtype_mapping.get) + + return cast(pd.DataFrame, feather.read_table(filepath).to_pandas(types_mapper=dtype_mapping.get)) # type: ignore[arg-type] def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: @@ -87,6 +89,7 @@ def get_pmon_raises(dslog: pd.DataFrame) -> pd.DataFrame: pmon_raises = pmon_events[pmon_events["pm_raises"].notnull()][["time", "pm_raises"]] pmon_falls = pmon_events[pmon_events["pm_falls"].notnull()] + # pylint: disable=unused-variable def get_endtime(row): """Find the corresponding fall event.""" following = pmon_falls[ @@ -134,13 +137,8 @@ def create_dash(slog_path: str) -> Dash: """ app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP]) - parser = create_argparser() - args = parser.parse_args() - if not args.slog: - args.slog = f"{root_dir()}/latest" - - dpwr = read_pandas(f"{args.slog}/power.feather") - dslog = read_pandas(f"{args.slog}/slog.feather") + dpwr = read_pandas(f"{slog_path}/power.feather") + dslog = read_pandas(f"{slog_path}/slog.feather") pmon_raises = get_pmon_raises(dslog) @@ -167,7 +165,9 @@ def create_dash(slog_path: str) -> Dash: fig = go.Figure(data=max_pwr_points.data + avg_pwr_lines.data + pmon_points.data) - fig.update_layout(legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01)) + fig.update_layout( + legend={"yanchor": "top", "y": 0.99, "xanchor": "left", "x": 0.01} + ) # App layout app.layout = [ @@ -180,11 +180,16 @@ def create_dash(slog_path: str) -> Dash: def main(): """Entry point of the script.""" - app = create_dash(slog_path="/home/kevinh/.local/share/meshtastic/slogs/latest") + + parser = create_argparser() + args = parser.parse_args() + if not args.slog: + args.slog = f"{root_dir()}/latest" + + app = create_dash(slog_path=args.slog) port = 8051 - logging.info( - f"Running Dash visualization webapp on port {port} (publicly accessible)" - ) + logging.info(f"Running Dash visualization of {args.slog} (publicly accessible)") + app.run_server(debug=True, host="0.0.0.0", port=port) From bf71e09091f557ea93cfa27187ebf49ac1287c95 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 15:46:37 -0700 Subject: [PATCH 154/248] get test coverage on powermon and slog stuff --- meshtastic/tests/test_mesh_interface.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 2f8dc83..f637c62 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -11,6 +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 +from ..slog import LogSet +from ..powermon import SimPowerSupply # TODO # from ..config import Config @@ -47,11 +49,15 @@ def test_MeshInterface(capsys): iface.localNode.localConfig.lora.CopyFrom(config_pb2.Config.LoRaConfig()) + # Also get some coverage of the structured logging/power meter stuff by turning it on as well + log_set = LogSet(iface, None, SimPowerSupply()) + iface.showInfo() iface.localNode.showInfo() iface.showNodes() iface.sendText("hello") iface.close() + log_set.close() out, err = capsys.readouterr() assert re.search(r"Owner: None \(None\)", out, re.MULTILINE) assert re.search(r"Nodes", out, re.MULTILINE) From de29bf34ef3eaaf822db854d0c968c8fd5836f0e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 16:03:22 -0700 Subject: [PATCH 155/248] install all extras when running poetry inside of CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 543db54..9ad4f3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: pip3 install poetry - name: Install meshtastic from local run: | - poetry install + poetry install --all-extras poetry run meshtastic --version - name: Run pylint run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" @@ -68,5 +68,5 @@ jobs: run: | python -m pip install --upgrade pip pip3 install poetry - poetry install + poetry install --all-extras poetry run meshtastic --version From dfa3d46a34f0d8b9a886c8176ea9cdec22f3b347 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 31 Jul 2024 16:46:09 -0700 Subject: [PATCH 156/248] add pandas as an optional dependancy (for analytics only) --- .github/workflows/ci.yml | 4 +- poetry.lock | 130 ++++++++++++++++++++++++++++++++++++++- pyproject.toml | 4 +- 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ad4f3f..c01798b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: pip3 install poetry - name: Install meshtastic from local run: | - poetry install --all-extras + poetry install --all-extras --with dev poetry run meshtastic --version - name: Run pylint run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" @@ -68,5 +68,5 @@ jobs: run: | python -m pip install --upgrade pip pip3 install poetry - poetry install --all-extras + poetry install poetry run meshtastic --version diff --git a/poetry.lock b/poetry.lock index 4995f5a..63c3267 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2251,6 +2251,97 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = true +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pandas-stubs" +version = "2.2.2.240603" +description = "Type annotations for pandas" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas_stubs-2.2.2.240603-py3-none-any.whl", hash = "sha256:e08ce7f602a4da2bff5a67475ba881c39f2a4d4f7fccc1cba57c6f35a379c6c0"}, + {file = "pandas_stubs-2.2.2.240603.tar.gz", hash = "sha256:2dcc86e8fa6ea41535a4561c1f08b3942ba5267b464eff2e99caeee66f9e4cd1"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.23.5", markers = "python_version >= \"3.9\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\" and python_version < \"3.13\""}, +] +types-pytz = ">=2022.1.1" + [[package]] name = "pandocfilters" version = "1.5.1" @@ -2759,8 +2850,8 @@ astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -2975,6 +3066,17 @@ files = [ {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, ] +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = true +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + [[package]] name = "pywin32" version = "306" @@ -3627,6 +3729,17 @@ files = [ {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, ] +[[package]] +name = "types-pytz" +version = "2024.1.0.20240417" +description = "Typing stubs for pytz" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-pytz-2024.1.0.20240417.tar.gz", hash = "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981"}, + {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, +] + [[package]] name = "types-pyyaml" version = "6.0.12.20240311" @@ -3685,6 +3798,17 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = true +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + [[package]] name = "uri-template" version = "1.3.0" @@ -4031,10 +4155,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -analysis = ["dash", "dash-bootstrap-components"] +analysis = ["dash", "dash-bootstrap-components", "pandas"] tunnel = ["pytap2"] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "c8a40e0cc2ceeef6297713527b8b878e29b763a3343e0bdfb456995f9303c09e" +content-hash = "c696888a3c3c82fb8908d8ddf8c917abba741c00b6f1e21ee0a489dd1fbff5da" diff --git a/pyproject.toml b/pyproject.toml index 05cf219..3f87d86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ print-color = "^0.4.6" dash = { version = "^2.17.1", optional = true } pytap2 = { version = "^2.3.0", optional = true } dash-bootstrap-components = { version = "^1.6.0", optional = true } +pandas = { version = "^2.2.2", optional = true } [tool.poetry.group.dev.dependencies] hypothesis = "^6.103.2" @@ -47,6 +48,7 @@ types-requests = "^2.31.0.20240406" types-setuptools = "^69.5.0.20240423" types-pyyaml = "^6.0.12.20240311" pyarrow-stubs = "^10.0.1.7" +pandas-stubs = "^2.2.2.240603" # If you are doing power analysis you might want these extra devtools [tool.poetry.group.analysis] @@ -61,7 +63,7 @@ jupyterlab-widgets = "^3.0.11" [tool.poetry.extras] tunnel = ["pytap2"] -analysis = ["dash", "dash-bootstrap-components"] +analysis = ["dash", "dash-bootstrap-components", "pandas", "pandas-stubs"] [tool.poetry.scripts] meshtastic = "meshtastic.__main__:main" From b0e1d961fd8dc60bcdb49ebbdda3c8f73dfd9ce9 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 1 Aug 2024 09:50:41 -0700 Subject: [PATCH 157/248] add vscode config for auto running python tests --- .vscode/settings.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index db434be..d2e2409 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,10 @@ "Vids" ], "python.pythonPath": "/usr/bin/python3", - "flake8.enabled" : false // we are using trunk for formatting/linting rules, don't yell at us about line length + "flake8.enabled": false, + "python.testing.pytestArgs": [ + "meshtastic/tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true // we are using trunk for formatting/linting rules, don't yell at us about line length } \ No newline at end of file From 8096d102765032954344d7acbcb8ec088e6b6394 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 1 Aug 2024 09:51:27 -0700 Subject: [PATCH 158/248] Do code coverage testing on analysis (using stored device data) --- meshtastic/analysis/__main__.py | 11 +- .../tests/slog-test-input/power.feather | Bin 0 -> 22258 bytes meshtastic/tests/slog-test-input/raw.txt | 349 ++++++++++++++++++ meshtastic/tests/slog-test-input/slog.feather | Bin 0 -> 6282 bytes meshtastic/tests/test_analysis.py | 25 ++ 5 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 meshtastic/tests/slog-test-input/power.feather create mode 100644 meshtastic/tests/slog-test-input/raw.txt create mode 100644 meshtastic/tests/slog-test-input/slog.feather create mode 100644 meshtastic/tests/test_analysis.py diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index 993f04b..c4d79e9 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -125,6 +125,12 @@ def create_argparser() -> argparse.ArgumentParser: "--slog", help="Specify the structured-logs directory (defaults to latest log directory)", ) + group.add_argument( + "--no-server", + action="store_true", + help="Exit immediately, without running the visualization web server", + ) + return parser @@ -190,7 +196,10 @@ def main(): port = 8051 logging.info(f"Running Dash visualization of {args.slog} (publicly accessible)") - app.run_server(debug=True, host="0.0.0.0", port=port) + if not args.no_server: + app.run_server(debug=True, host="0.0.0.0", port=port) + else: + logging.info("Exiting without running visualization server") if __name__ == "__main__": diff --git a/meshtastic/tests/slog-test-input/power.feather b/meshtastic/tests/slog-test-input/power.feather new file mode 100644 index 0000000000000000000000000000000000000000..f5f14536992a512dd2ef895413d692236a40bb66 GIT binary patch literal 22258 zcmb4q1#q0puI8ATnK5Q&_HSlpO3ci5%*@Po%p5bs%*@QpOfkn4JI>~ud+xq>U)65y zs;XQ4b*t6-H8nk&za$Y=RV6J}5a{&CJ=z!t8JP;eX^&L70E+ga*Oc&jkkmmtFsT z|6kAGYGr5kmxX`H|79l#1pc=_SpN6}^KT6LqXqZR+Fu?){97Xk0`hM?H0=Kf{9%Y7 z;y>s7<)44aeETy;`KSHmhf|0@-T$V)&Vu>pED+dVUj082|KA?~2n77Y|1I}#%#HQ0 z84r?wuly(WL--edru)zJe`DJJcKBbu_)k0k|1t279W+hMzYGCl1r?Bbq6U2D@)IF6 z=rQczq*=3TZYYzhJLancX3u*t_dS$xFU;JLP+w4WCP9B)l+g=>ex(u9AaRSWg|I6P&Gv*v@fMDS2Hz?HcCTz;LDeo5?LMbHcWmf zpRu9vv+mjA$TT3&iejbad$;-VC;!`pkKgl`PJt6mEtYSqby=eb)Tb3x-l=DmOps@* zP-%n?u3T>GFa0$|=^vQ!dBy6CHmtJ1dM2?{xx~$u%a5 zb^rDt@8_b@o1co1Wp?-bvS4qz_^)WD@`f)tI^^$|h(lgA^gXDe}UGl}Ka4aRyG^-hPDtlNr9kiz3EiHLh9u;embVU*zBsuv^WsfZ^#3}SE(e1nms^e!xbcVvt_I< zFwMcOVN}+Isks`Uc$sdX#Wk+VrTtWpj;>?xUw5Ic`#$)_p+{Zt5lJ7zkKuwt+dyfk zmi6OXp*GqlcK`aTQC-8EAy0Or-n?RTzp@r#Y$05dw?0bS*|+df+G`|+zcX4p+%F~o zjz7v7@SN;|6|T&5oM8vYSzUy3)!X@Fy|M6WTHcfJPHYe$^GS%Sebch?eON`8@^fsQrSQj1z6AxiI>@hI%Ll%9f-?jm zX0gBp|8}cCdR7g|?+sxLMb0{e3G@EEv0tPTzR|r*A0hE&8YYs_bMe$kCu(aGa zXRrp|Ps@~LC&8EjlWAU;1(p37dWC4rdH3`0D4df=mEU7}Ic9EE?gVp8rvf6m;-bDf zY4v>#&*Lp*c^%}xc=?lrlf5gvK>4uXjkv$vpglz6S&q3*EZ_5u3J8qh=OGsoPD_Bo zW|2$n`Pz+dn4<&4MS~>J+^;F1G>qzd*y1}lPBIs7PanTzm@DLKG3c*_Cb?cwU!m@P ztj9@}6n&&^5@`0CDkd+@r8wmyNnuL0tttSONkeqwE{9`A1n*2e)tZ*Gc7b<$_vH09 zu~Z03#g)#K*EaMzjgK)}OF>CxZ8-FSf;c$ws7=rna20 z4JwZ2)!VXt?pQ#)qoz)lxbq+?=cl|y*YP|K(EZkcMA8EhqyM^L(Hp+lBhuGgZ${F8 z9{uq-)N+7%kx_Usy&?o>s5w0CN2lR%!wiSOh)j71&Zt6I?PIm+SiyX+$hh0LB;twa z7@b#gyUEA(V(BTfHcjej`cxOlnE)5F<895^%ArD@Irg$J?0J{a;rk+^1*_Ru;YFz$ zI^v}dvA1u(ZI;nD6lGR^x2RCB>ZhSWt_3@v?RG1z>vVT8Y(!+8!)^ZbXgFck+&UQ4 zWZyn5ctqKu^mo6s(%%IpSb6v2N>4HOeS#jY>kJMo$3=M#&Aw)%A1V58Ul?j1&kriH zo_s2}!9GO_p4sr-!v3MJaF${g)6v{Hz3`Red{bYcSh?c~;{qCslOZ*rH1IzC`aANK zG1T`@Iv%=XPKhH;+sd4mwp{HBUkXc#ez%99T{RG(652($M~3HPJz+e{pR!l;+(?Rs=`7U@)*_9l5Z!7L$8k=@jKm^;wS1e$ybF&AcrY-&pPNCS1^@6v zPLQg~ndD(1n)s2&3UPT)^eL*wiTK$#y5ULC!Ifez%~ zp)`UEe{FT|>mr~H6fuz#$wq_&a_4eRXw8=_!?cSR8nqzGv&9t>#(my?Cyx zQaA2&zyZqWR|=PRjDtX5e@+A`uVsRcQAk#1N+`Bf-|+bcTHmt_>xlI)@a+s;iIj9? zQYzwVGs$gPrLx)gTiMS#^@ghpmgROzDPA4z3wvTL_td$~>YDs_83f%)zr_h%rZwsR z4p9F`{K!}i`f1ds%8KftI1dIpSE-d{?tY9!6X-@=!CS~ui&QM#&4VHM6E8rsLM?5SW;Pl67Qz)r_eQ23Gd)TwQKpF-E!RnDIAd$#1uG z%8hTB;5&r4Kl>{f*w9v4;wC){Zz7$^(ohMO&OfOgY+Z0z!9H? zW$4;!Wqom3{>j~ddOA!!QnY?E<)ZP%rO6LftD>o?q*NeXt)+p6T};p|&aQ%Oc5o`K ze8{)~-qK6wCG=hdBLQx;y(Q6+)l||fyag*N5w6y{dn!=F;LEc&0aGkVRZX3P92?kJ zsMdG8D47~epnQX(AoT)M2@IT&J=G@*vr3u5Q}F#bRa{K>`+kq?CqQGAW41NWTR*ke z2!M6&EhB%{7+8R*!lM(c*A@v~@J>V^b3)(uILr4PGv+SCF2q8BVj-|s5GVAHaBg)? zyNxL@YuFm=n1CvL_@FWxI@ye_PR!;+rrjpk9OT(eG=_Cf9N}wB6(fCy17$kfEWkNy z%)Of=mr3QR#n{vv`37b%(Bq3~GF#A~{xBv{DFh$Pq5Em?@g$Jx^G{Xv03=zf&MbPq74A{Lga)DeG-oJ6X*k$`8#Ks+{>YWA|u`H1dUfJFQx{rejwE zkBIkWbg#bN1#drWeSEp?9|p&w1UHN07O-(AJL*fT%It36T?P=s>V7z;Be#Z{A#B?P zG)lis-rSsLO%oCIZwoFL>yPGm5VN!Kp??1P26=6x47c22>Dqf*voXNKK(l23vpX4i zl?XlZ)<*)YW-n=XV>%*S)Np0vkv%Gfv0^4kI7hY5F1`S@De+z3Q?lQ6FfQqA>!=^d zrjwp2SOcPN20^%z-({dnM-9_UMlCu83R-~93?S<=*Wf2kdQg{r8uT!gTU)iVmR;#z=NmTn5wG3 zmtPL0CLX)KWigP>#*!c}*ikyg*y=^7e_R_v^74SXjH{Sx$sMwOlRkov_+vkn+iCb8|;+nG)XYgC@5_{{H#*1_Pb9l=vO_|nd9=I(|DpvfLIo#TXG>llmSx=@U+KD z)~(=rC`sD96C>{%$QDg-Z9Vdg{+3u027jJ$$u7=_0dakUKg+|#uq|Cq;i_RG;PWcR zj084y!kmhu`@0uB{%MoaTK7_DV4C<8ZOPa6Y%rtaqb&Int%z$@6fkT*8Q!qECb=N}f0EkUbWZ zKr@5tW*}8WG%ZvqaxP0xW_||0ck&$RqTJdOVYwCvJfw!(0x_w3!XU*8i5K&6y@D zW79kz4v#Y!+!f1XV4oW9ZZY@HZ7PZlfy1(w%esnV?-!r73Fl9CHc!#pV12%gAEHBv zr`qEY>1rz37{{8>`)L;2I`f2#U*g+Dn<5HPJF`Zw20hyE&?Rc=NZk}h2BYCw#F@a- z(u>)jSkYATQ)n`Zs~jL4vRI^bcEsIyc;l1aY_KH^f=GL3YAOS9a|s2uJ&D-yqMzQZ zw0R2LF1M`Dz7BwMJG7v*1H^^JiRAKB4Mz^Ro$#Op9Za` zOeV!hTSXU*{uTq8deLd!F zr=_IoywqvOqU?Zr+39^k16EDW=j*xwu20Sz2k25%Dod^1kpZd1hm7wCwh-CnsI@a+ zb)Fc-+;~1;P|5N(AZ!i;^XtE@}-bWO+W}<6?DgP ziYG<@iZEimCTP#6RV@(EOzJ}DSr>w^@bsc+{DC{&6j4?)cWe z06L$H9iF=n5oKvdA=nO5p`sSN&n=H&k~rQK!f;wA%lhR@IM8Y&&i|Bt^%!Y{GW3)( z2T~Q4au}E?lIdtV(J7=PIc*l`_EsI(;QHBl6wUF2VVd9CeE_Sv=!BM4(NI<;?=vnQ zpCR6Z8@mPH8rG|T*GVv3$Tt57*tKfN(ugwuFwIwyVSad*8kUlPZ?ZIZ!vznt(#9qXvXB06+Pc0#J6 z?gTRh2q?;Ub%vC~Xb(Pa>e^rpE8O~hFsc-_9r1>jb=Q<#$>KgAw`m^n#=r$noe8lJ z*jiyMYmFZ=)V`-68)G-bp{^4Ha>ZQKO(IZzQJ@p__kpV|?$#g&tIJO@+QtStjN2B4 zs9jJn!9^d8Wj?_!+!peLR8n;~-Ufy(#nrA<9#5jG-Fm)%e#p=y&(#DM$cy|853dZC zrWTtt6%l}-?#BM{AZd=Gfs9N{RESj7&Ta?NPtWnCTWE-b&zvPzhH`9wE(7xThl!2c z_|wH?S|+tdy5U-gLj@jG9V#O>T|DR$uR4}fuxcL{DXU&Ez*yC<#DZCD6)A{hU-F}U zf(XxK%_zP4EJ|OB!#4x_a4;k;G$N zR3*WrY=LhQbt$sJAx<8^?%b+u<)fMi!kuu7*oL8HL^vLz*`*t%B>f^LnJ9!#3x*J= zzU+ES01@MqI(B=>CvNnI>1ahUSrhEE(Aym$SDoAwNH`!IEyr zt1FIjZaw293h?yh5nMycvL|KK2}45OW> z6%V#&os&&2G~kIP+2-Xd;0oCeDKq|RB_7K0`I7@pCV#fPfCFxi`WvpPkPozM9C@I( z!w1}A4?p`{lngc>G*7`-VoZiR5qG#J{34CNjpg{lSTXkR#`o0pxtv-EL zA@XuHkc$&kXn zwfp`JJor0!rw#LGSA31GQl76WbD`I)#ibWP+~X(PJrV=#1y7181RuP!<0-PC#y(k- zOg9}QP@WtaJgT*arCcevg^t6T`w5xIh6N(en-G@@<+k}>vm$91uvzCFSibWJh`kIa zJw*jeUGJ$OV;B-pbS|_D80q%{fc=?)K5dt$&Oz-4lrDo?B2627m|0n-DYPv zV7q^Q%xO0y5PNEiq)Aj%+vC^fxKX~^mS%_@Ty*uc(1}d-HM_&TvVv*^2@9hQh=Chk zvsz_}U}_m{f7ABy^3wK@Oj$qp^FlE_0B)3yF?^<*2ls0>u4ju4cmthPE}jD~t&4>K zM7@!LSfSUXIO=EU`M4*PxMI24u94jGCdP!k_qCQIymJR%BBn4o~< zB$t~#0~E0Cp+wsb<&5#zIe@k-Wfj|k z(oia0fP3AD4U6m_O#IZ#U_wy;64q$;J@o#yid+G6^ZT+1Pj08<^Jo?Vyu+Sa&{JFh zsW~|s#EdK@M0zXVtq@uX6I$Yo^6@xify$n5Aa_uX?(6|sQX{|5py!2spf#SLuW%3@ z>+QE2fnj$!DwZojs_`s}o9Gq<1x#jHgB_fZ)rh(SZ(Ac6O&~kiogQ`f6n^I!8mWjN zN7WPbrCpa$z=4C?#L(MB-~@^cjPvjr5pN#~3q9KJf}Q`yRQ|mWzQMTvY+|g9VrCYx zyUCMebI_<}{H^h0h|U=08E7x;T==j zOzx-hKUb^v&o>Y>a;h&zyhX(N*4PyHbk+E zHQ>%K@d=JTB|y#&sv}+tXtu4;p>8Yh+6Ro0`!WRGh#yqW@_!F!OdZ)b;pOD{Ky}z@ z^`qF3)%Vf#xkWxqH@y5;({l;$18&Q2v6%294$YIrIBrG=+bk8-9CwP^N zE;We~J|c+M>%-dVLwI<^8GHV;7F3R%Sx`8lt1F-SoZ@*>r>vUazkE+13$N-M6;FX# zM*7J8v?(Rhzyd#=HFOz*>Jd1T4d*i-k=FfW`5_h&*&xrw4k`hmd2Y=XE|Bt<=+Cd^EBlVhV3K4UwE+O0YVd8jDuvy5+uAMa1bSCJF0})vB{Lqy zL?i>FDEQ0?mdI|pm&~IR?90Rm>S~K2;&K&MLwwg^;bw}LK#LhqwCt;Q-Y7iSApRSZ z2u=C{$KhK4wv~s=DG?0BJ#6*&``joc2rIO0^W5fQrI>9!uZwT}>N^Oz<9shbr?Ay0 zQoMShkw;eZeFLFw@*uMb;3Z5Pb*L9U#eLN{p4K$tDVj`iIDfDc3e1poUg4gJ{(^7H z`+A{<*j+z&o50z%#nsa5I|O$|82*Vu`e95QGBdHB2v6N3)R93H9s=ak)N61i7fC~f z1GQXIp)0MI_GjRFXxk*AC>QU z>QbFl<4&usn~q_WZZ>4k2TLnSScOGZFN&T586;=kl-vQHpK9_ zz8RNwz5;M30py*5{S}Z^JY5dL8_IhudoQ6^m057zPjS!`mN!2-1qa^CXnuA-00LN# zpxb9Bx=rZfT}#lu&vVV>G}qz;&qL^mjV+|D6$tX!#t*$SF3qE7IQZ0ADr#zls>~O+ zf$h-7q(*%e!uFRgN`5p{lb?+yzJ*l)9jIQ*Q{wXvI}~vDh5+$xq~4E)_>g@q3JDP8 z6p6cb#Z{3Fn94iY9}ddkM!Xtu5vUpHlqcy?FNC}F|Ci^X}W^}L}o6f{gZU|Kolxlv}Y z`+wgdgSnEyK|;bF!DS^4vQebvg{!-As2@Nh7x_DQwkC5h8}peZUkYUhyixH9lNmM? zt|RZJCm?p&tE(6mWVKVblM^B-$XbK`$9q#VJ&^k6`=#=PfEW{?CnttfK}Z&eR&K-e zcUAy!xH?QjJmcpb3E-aC*+<7ELY( zsFxPzxj-oZ-VPA{-0rf#T|3;V_l+zt)30iU&4RsoW08U=+iB3f8yGJQELivY7zxXu z>BOxw?#TmooT|yonXG`26(|jC`FlxM8q3V+ zgRX;HWB~lEOl|*eSs)E(xQg%FXx|6rZ(8!ef~$l5vZTVXb7e4RmJDDXy*H8?BMas#XT=?a$@R~KFLoFjpp*5+ciQQ5iesqJ2MqAs;tV2>17n z92Ss{iCGLPFH?Z?Y5iphSAkDNhOwK9OsZ?2j2FNW-759G&M%O2?hNXGk*9ZQ=_;t= z^BTzN70c{-3lHnmFPy<9ifSX7^ZE!->uv};!3?$T4my7sNYw%6#$epzus;D7Tb+%; zzx4rL$h1h++>bdNXi%GapXTWTbQ7gF9#4Pv8L*n`!gDu$EVheZNJZ4INBKE$>ZP}l zr~e~hRr2=(@nt)&q?T`LyTqlpN$jy3nzWheHB}t1cn`U028^gYj7MS0)~KpN#~@|E zR|QaYE3AF?T=X_)kFG3`iK~*#$~{$wu8tNbcVDeAuYM>8gkq8ihde3*X&d{v3~h4e zXcR{5H!{F_5rnnHxf<|-Y~dO^A_qWknj{WQ%0^eX4BvLz8T_hsSC$9D^Eani_hmO2 z$37V|$Wu$xvqJ650CKf=tqn~MUgSC~)^fx1M7G!JiU2&mV*zTc3^4F}NB?F?4lq9$ zscN57Jfcwxh(?hI9OduHXZhswbjl+)S>yo3bQEHfcNw5Ri9T-RT^5jiC*(v7mIt!# zixc&oMDn#heiy>gk~TB2o8JaRPWHp1OY((Wq9u}=lER7*T^8ejAYy%8+H7GDdm~5;f*rq$vPIJVP>Cno5xl+bg(^vVa^5#YKFvH0gWsXjO+| zWgps{ev2#sMswK6e4;SDPmiJ_DR-8*1XVLAC8!F8W+fpD+a?+Wxh4-R`G$(jdCQB&LP!QD$^(8H(Q0QO<$==J ztHAVb8SBBv3}0I%z`{3Zu76U-;GPTi(t7vFh-=eb2AF4Vv>x7+w*HdVzqg|R?rOx) z>@TN>-DQ3Ca-aK{{L|9n7v$6DP}%e&6byzB@^}fj(k~cFo08iVSDH=c?R@228c2sh(H3=9Ov5zqKnYYhC43X!yOjpoaYlTEQ{~e9 zXyq^cWaJv0-&Dy4Qqf_0U+ph zBfAPvOq%biV||wgszrJ``3V$2R_0NTyNU%Ci>ij>iZRK*8w$Ab>*Fg% z;C)+czgt+y;Pxk1*xjc1`i!AKz|4r?F!9R@lC+szsRxWm_~)2Hhg+_PgQN`6PgFl; z7R7j`!L{ms1?ZhU4oDo8$$sJ!9a=TZRx{C>dHGBO=v4h)J6+*C_j7sXzF$BGf}+v+ zlCIpD?(=WBJAk5xKqcu|?ITsAb<%HW84Z1Ug$E%;;D@$Ql9)c<3fI8og930)iu2+d zA-zQXaT(TMNl&TA;hW50ma0ildb*jK>|}-RadD({VHl(q46DL>UE7MU0x$MB4|b!1 zl=72=t&B9;Ibm$duGAyZGAS0FQX2z(U7D->BRq15zFjc~)6jdUOfX%~r_@U67qOf` z#e_E zbqDs_XB%d1pY)N=gXe0j#}3<(#bw+=m@$TXTE56zocBBF3_}r+4nF zE!U-fxZF@p0|D9b%JCf=%ge4GR%B7($=cfI=cYv6-wy?Kbxw8+Fcc;qHx>vS!P4bh z8ON}yde-9kawoa2w?-)PLpL`>d19)gxh1bJ-SQP#I!-1VyBcV0)-|gqFAjc0jBw84 z&oUWTwTwd3rpNIMbm<(#um^sW*L&fN`BumEmCa)MXQ~g|^Aie1X3p=Lbu9kv(y*eV z_5qilu2Cl=ZPrMA;#X8%?niI_Y+U`EDUa1wg!TIL_N(0I384e(o~2yuEJL@(1Sb+s z{S=>x{O%b?R{S=Oc?I=cXSSP!_p0l{?+2YWw?(kONt{4i-!vGon>6kSHS6Q0EL_?l zuF5O48QdvSOtD;Ez>YiG@^@kWcxWZILgaaub*_LkKsaC;ZuwU4eZkO>JnZh0=37(g zuE9@PuYK(itv?iD=d^P8)9E!N(OPWipou7-qvvxCTY?tj!UaAG==7Vs(Rvla`JCVI_azNPt&Qh=z%eDw`Jo{qPNi75fFIsCX z9EyZp$QN*L2?4SY@y%`*1P5ZV-j+gujHzAd#jJ=;kJi9CJOJ!n#T9lxi}04?@-XoT zi^!-~SHw*?7-I;`3IUgQ!3@cYjg{7nCcpC%U#<+|g#b&V8!!Aj5ukD(5tflyxV7Z_ z5wEQp+#xYN@~;~fybe`2ljIz%z$fMDxGR&f%HnJ*^e#pEM4EB4=smw@i@2*f+vKLZ!U#3{;z8g(A*u+Sip5z&}6QyL<;8 zsT`seGQ8+#)8ca1w~F$0T8XK=wm(RC79E;PtR@7w;a4JzFnAW?F*}L&xalFfzJ3P@ z{S)TwDN)~+*%B4&Vm#9je*$#z_qoo zl1GW4l_w9XQl5C&7cb7LN->_Sh)l3M0liVXFhX9Q9Di)=2!^DsE1MbUmSnKW4WtXOkI#7e_5{Ph&MHxlhPbSR&|HpQ>C0KqZ%J%p(=G z%P&pdwGz!pTM}TTe{U%}8`2T!(^7s`&;iWj&0kgWg>svmk-dP%dg=^wbLry^b!TFL zp6A2&BN4`M8Wr_QrLlf$zmKt++t z@&AbmxC(IVzA6f?v#0xhfZ4xq1&?h^Eq`T-oZ>HtJQnP+LwIkt%L1L`J1eofQmIna zc}`sPz6>0Wm2B^5ay@X=qYNjzv%1Dan=K#9XH5yt8s0Bg!4x}2L<>G?$Cq-TkL<>2vFk0z%T(vv+!u#V;OUDc~24x_-ItA<~W~-c; z^?o?cOtXb~aFoWI4UL_fL_lw+-)^p9H&T0y&D_CfaxhshazGgc!hnRBuRt(Nv1w)) z`J`OJXlFi+kV(O2)ygE7u862BZG|<3YS-L?mW78RcmCyt<563fo>M3om5RG`8%Hj2Vvh&DcklY@v&-m_=^X4%G^k6^ z-`*CVns>}yWm6=9$Ymay2(0P6nTwxrI8|k%WUZGsC~)uV^u7=7#LTeIkOzOz&S$N8=^C(F`nd-4mD+FL-8A5m*e3uyIWue9xZ6@~Dr7Q8d?s!eLfgK|p*0VT$GB z9eKRA*|JYF8j6U`7+*AW=13{R9HpH%nPIrteT7;5+^|(y&%o$k&tAAYWC#cuzZ9=#lrK8obCfE>=KB$@|m|}nrp^38$U}vJ}x79 z8g3O2_gXf^bPno;Z+IYt+e&qqs-epBYqSb2srFZtizvuBY(u_@nt~bCr*}w>k%m3; ziCH>w7cNlU4c~q^to7dHk}+HuM@t||ZA@A5@b9u1EPETyxo)7e4S99XDlp1tuZ9eE z()5l0WveNIWbXu%_jdHvaxeeF&a_(-+1x0lj;Q&1r|59_(J^TS#J{htef4?amwoGu zLTg^vK88y8>T*pponh!sOmk!C{(1YwST@Y$>du52h2P<%A*1)iXLBFXEpcJZ=v1JaZ5i^i@e%PQCH=b3~yU$p~y)2gez!#~?b>h9f zS{Cj>A+{CySC-?y>aG4?>WfZ^|Eq52|5jfF_a_GVFZzG4FA9hH*RF_v_`h}h8^8Qj z`1OY((Er8%-Txc6!2D|l!2kEkf8v6_ii-ZBzlQ&5=l?&J{#St-=X_RVu5QoCR zBk$^8DYbpowrDjz53NnAcAaVu))}+;b6clUqV{4jx^;Dn^|<4{^bX@ zjYKI9ym=eWLr1_K!*5$JCq$)M0J$<|yV(&!~l6SOFU?p?a|f zi}6WP*LgAmUdrs=9Q($PjYb{u+gw`vuxxc({^F}{-5w@eTTPE5&hQOh-ULlY&J)`T356tsW6 zq#84!#<-uB@~n{{r0Hr`G_`q@J?DNMB_6w-t6YA07M3C8Rr;lze$vc;>M3U`AkXZBEDUm(+sc(FLaZai zFLn#PxT(_lS~(EGQX-r|2~o=IIJsdXS+-aA8?PKbBILG5uYzs@oxAcWZxX2r+#_z! zQK@>O!1`y1 zr}?;u7_~*gyZY?2TB~EXKYg3umm#qBY}?$GDX|XZ+E#+jhj6QV^^aXLV-y_SdDHMc z9-rg(8033bTSzJTBICDSOwIapXAAiU#=lac57PS5oRzB$<@Qw24vVICykA(4EG|j` zqjTi~7-KVmsuv7e;~ae?j1xc8Ai*amZS_{&MW@zkW^kvMgF#mhIx{4L`;4;#UkD)P z7VQkzn#Ja^YN_xR%t9frS9KRFhG5y26tlCSmvbDOH`gRr_Ua}HR#U=?Z^-r6c!$5R zt)u3!z;1kW-rIsx+Dz(xrQM=PUA;np*e=oc|Gb|qczmt0Gt>=3w`-f`4zu^@!oJ%e zzyGUcj^;o$g%<2^*s*0pSn5w^f*Z;4dkpQ36P#=l4Q~OOEYm#jCc?K-%lYOk(((ayRM|G4dywANQ$XG8WVG)c!_rGvKzG~Q8uSbf%Io7w4|8kBe ze%rEqPhYeY{asz-KnPl^i2C&0V*+L~>n;dRS-FG_F&h$f3o?Z4o^0ZSA}fW;^pLxIcll{>H1f@c}jVMR#FAwfW_aqm2IRzXVaBBDda`Eme(GUPD2 zsVakd-Z)5xrW^O`=ejxi?!t;N23=(b4kmdp!OfH&)|XK{4s5P`GXxx1kF0|UCEVk7 zG-|x^q|PqENLa=zrY9f)*gJ zRYNubRNNXFK7?;-)SYzwwOI{0jO6-HoqaEOhJ>hN)`sJj>@pe!lTfyU_#4t2LWGMC zn>H$2LDCDuq83(4{1EUE2oN)xjN&Z2qTS5mMtB3EcT*7L3;h}w-ib)ddKfegJb+s3 z!2HPocahu&gzY%Q!L_1wFJ$XQ)DMzJQzs+FqVd5lU9|8n8Ugz{3^Ir%yfkrgTC7_i z9Xe;851$u~1;1Rfw0Rl$Y%lDOp6~y#D=D*{MANKc5v1?dl)eRt9*7(JM1vTHEHu-{ z;2BXou^80-U+?mRWxX4w*E?d2#YTmeF3xdncNs6e@;pw6H& zXV%-re5tQ8JMs8vH0~_O^e*NyB-?nOt+j}yM_uewfP8qnJPuo4H3nbq=kiQ2CyF5b z5Y;zpT3kP2h5eMaa~xyz_+RIR=;a9lCq`WP6nZa=@!&>R*(t~6^CH~&7`2&bFqTpJ z_5}%%r{KRvzkZneA#!}JN@cr>SK_d@>R5bFdtV))F;L8m;6qTF7ocOidyT{>OQOKx z*Y3*~NZ=C@Tkpkn^98ChiV-ov2jN4_^+WJRTa?-+I)`NLMK4+;w0U%o9ly15*YLDp z#eDT%>GPLM=1{zjb{B~epGUt&e=^SGw`JuQJ=xSll-R)*v9dutFt1lRlffO_n#3L^ z>o;kI*&jF%%sWorG1<%`iQhx> z56@r`%X?(HXV-|%{JbkD!JjPdn3YU}p(qvKj>uA6C{|w>V>oKzCj;Jt%C*JBVecGL z2wAS6N&MyJM$-bn`bMvXUU5_p@9@+hO?leVZbE!k>uOO#ReKzk?J zsPqA#uWMII-0mdKcf>{LguU{+kM0UJV2pRhBLm=r5(+NA<9xaxig!_hv zo8=oCK(w#_ruWogAAOaWckbYU9%?nhDC@vD0P@+HC-uv}HTfS5tk_K{HbX?gpVZem8xPXgA zzRLyC^T8#>_v4KlzHVB)1&1A6>`$-oZ@X(2MKjtsRWSuBu836i<5oC7x)v+!C^Q7S z`>im?EPM6jN?@U5HMYYPl+d;NdEIgr3BmLZ751=@(n8uy1{J%>9OOrGv~*n^D}9o| zonmLtJqhN%QGKrO%YqG)1JQl+@V_k&Ol}@=5f`h60Npf;P{MC+tvF?t!{_o0A3%5W zeRf>gkV;VBjNl$=P_;|1diKd;fe7Iiz3DooEyW4g;~!k@@V&hC+wX%@O1|}gG~Ayh zh(b3>3@~T- zA2S<2a`L3r9jcX9j5c5s%38+BU9;A4nW-;t2bj_hr$lv8P|lBa8M@T4csgJ&%y-D* z#ji24JJ7K)e{HzpzZeUL>TaE3F{c(#T=U4HJFe~yxS{&o$6isif7zQPN|H2T!Xr6K zGC0_xo3_v<)6fz(U2>>?l65M9XO;RmWro;HFEe#ZsMf|LRn_U2#wp^5z>anqv4+d2htewfceMQrPx@Pin8XXB zU@(Yr{EW_ObIQ4as2lmH;E9x$F86%QbwmN^Z9>(NAJ0OaVm)z?d4@YdT5y`xz|Q7K zlic{Mi7Fp64Q_=4j=l(KD#`YT-d6a|+3vi6R{mhN!>K~#pd^JJlR^8GI?AByDN#C( zOw#xhR18Zs!z;V?_2y8xKE2Sa6hvbE9ez69>zh~G67gl^<&qPig^92?U2w)swr;+~ zx5$d32()&fBh?>_DUwczK}J3(Yk7q9gBtGycB%s`J2{KSXGAZ}*T^(tTQkyBnSHX0 z*W!!N0A-hpEom+$7>fXWn^3~oD(hG(QX$E{b|cJW29X*hyCHHGP7{)NwdUFW**`}}x*IM;Q~`*pqLNHm3Z9ev~>`&FxrpCo3# z=?k->D)ipRirt#n#05iVGSPa@A%#0)S@(#X8~MVdZg{LFp9SiLNq{GAGGElvPLau{(VlyymrF_$r~diIO#>Bom9BE%8%l`lN_Bx zOcS%rOLv_J*dLltUJ3l69=OSu+txTIXwMSi`av^<4{6&`GJPVuTht(HgXPV|wvHD1 z>z2&tY!Z{~q2_@_=T^$ZE^{aG_G)s-%pKm#=gnNyvg(2+l@wcF6*E-7C>AGw!G9~h zj~4tE5ie$;j$!qGtHJN-6hWC=#l0e;>2%#rsnw4jp_M{&2v2psiO6q zN%PGgjugL|Uo8te7WF}7D*b3&hS=Tb^usF3D*XD?)A%I3!~Lx3!HlUI%0fl!{-g8S zBMxE5%=&%ZCFYrp?@$Xu^0{RZ&qRw-L)Z{hn`mKN7n3l`Ti3p(+_zivNyQU7=40?{ zL}!oi1c*i<^zn~p1C3Vhj|c9W`u0ZOdV&2}{lopnM-E}1B??MzIwdCLVsEmA zGp%O2UbWO492bdp9=OY=H-Rl+_lfClmNQCAir^v1xW^ix{+JTY_3vU5G+)l|P<(95 zkMg*zCmON#^tNCJPQ5MYHv0jWA=~D)vHVv#tZUnXM{}bHvtPLl@bcEq6Xy9Ebo9#` zipZ>E8fu2{KGfGdB%whq^WeA?;e*OMUWT!teg3qvtM5zK zViWTIovtp{Eb-xkq4Y1oe*ASut{wcc^+xdfneJ4&+EL5YIPQr^d2#+)K`Q$qZg`4G z=hOY!a5u#19$){6Jg2~i#gj*H>X$@Y>PgB zQZ>I+b3Yz8&Xq~tZYDnB*~IfrdA*}{7UqSkI_$b_QIONaaXw-W)eyuT*x?QBov4yR zDK!+|d~vYm`Pq{#D+esQ&!I-^hZ6Z4>bBN}Lh}v!*HT=VS;EJnHa-Z%|BdJ+NVD^o znKeAK9aHPq<9MSO;KIX-nX~EM7Z_9u$7VThQ<$W*klZHn`V~&(Ne%J*KJhU8 z5)xndg1MrjdiXG}fK?j3XvvjrcSw(+rrmjI`Rq)nHu{`akd6lhx?>+vf9be5_eq}# z@0b&)5OXp4yV{AmotqiS`h3^?mTZN>jHM9w>M4iMG39?-)QygnMU@erJV)WrRFgio zU2t7vThF+2BEIc%Z~BVc>+YC=pjgX2euR}9=aGXR1*_{kf6gxK>8_*?(S*|#m$|HI z)m2r593F4G4w_D3@-b!fj86T*F5J@8N=jFrlSSCP=yY+@k$12B5ZJmF=RVaeGj5FF zHEI$rG4Vt%O0lK3S#R@uo$o^9OxrsfF3ZC%@vQ`^`yOMC=ZUDKMb8`Fy$Jj~xK);1yM`a9&=va9u>-r?c zAKkCi*wbZb?om3gZbsW5xwR=v&Ee#Fkg9q=ipT7-NBm^ld*5BHH*W`rHr_qftL-o3NQCh+p2tU5OmDK4R^V! zT*j<=x+AQtm0o!?7MU<`sr%!d0bm_kI@v_K3i1A`C8(vZceZ4@JuAnZ|&Tu;M!;NpSTtGGbsv-op)AC=Y0OpWEb8gu_2I+7}2E!5-Xf_DwM(AGM9_a+S5fHf0 z90u`Y*$GfO7%>`q8g{6-x!Lh+UE_!`g^)P!3zQKfpgAoje}?At8x0NE6YILs0Q~{V z4ESY;aFIf!qP!-VBZ8|nJW_BT^>`1TVCzYL-`Y?A2vt8H6FHupGHc#*nsO!iwJfvW zYu+ZBkG^^!VMM4PjY=IK51#lr`o|A4B5}KdjrsLnx+ktxc$dgYW+xfhD+rwA0A#Xje00_4W1C5x(qO+#hLH^hmtoJF;j8pG)4ZaJSrn+&NcJpuNkL2%`utBG%WG-dxO8G)V z)P$WfEJu2D4u230u-+0<`<#k7RnXyDhHvWldOrP)F7T(n_ePW;q{VDtmC2oCMb2JD=7PZP|$hsv}5lq6FHYh~UIX*`fgc!)#% z_q}DXBooU~z*!&|PFx`lNd%i2TpX(pK9j8n5CVV@uunKxE?$t53L}g?i3gwc>lv6n zc&edFg#E=v7p~Th3Og2Ol33i3hk<@&oBVvD9#9-(Gk+ZXsc9hltenEW57r3)c0k2Q z&U@t&2G_QdvqPl~puA7}R9gr2pk|q69olt$07M`aFZ+jcf9XSUp5x7h7{GUcUVs>I z1ZEg|5KuZWG0_DmgrRd_e*&Wk2#6Y>j9|_K%MJ*3Knzs`Tn#Wi5X?hPL$EZ_gT)6! z@W9@JVO2;xwk()rU7&S<>3{`_9t0>8EK6Xia{4!xva5`4avFlQ z1_S|o0!tbIi(p0q!xq3zo~96D*WW-eNCBDzAQqUaDE{d+qk@HCX$9C6AV$DW!Dvbs z##*zxXQ1|SU0|?aKmv;zhMaP(9`P*W)Pq$PFiud2XORLm*`+`U)fbLdSIG6+*^>ft z)#|UWf20L!+(LLz% z_PTgxNBd}qi^FtsniDNAu0*%|S{|!(25an?&^3E?&Qy=Dbz!$UC_yFhKF{4mFxjW- z+E&Syc| zbK3jjKDTFzbT*oPl=Ni3DA={TE=%nAvXIK?$E?`DHoUCp*a_F?H3pgyT>lJSBATfN zyAKp6Y)<>W65R4Hqp(t=ZmqqUmf3K(X|jqZ+_RPb7UJu6t54yfi9IjYU6?-|hir%@ zr+xdR;2V2@Yw+a>Kc{bXqr{Ax!;6L7R3`Z-Y=ESSjB*Ea73U*S4p)-V5A1N&V6vKr zg@C7j3~ySip9P`Dt?F(pqG#m6riJO%7S6ofrj3=yxuU8C4)5vTw;<;w^plTMHG_rj z{_@l#yLXdG$Wd9khWN*;FTNWXS{JSE>ao!$c+E=chs|;tof3KQapg(bD$$nhhNRcn zwVTiC$1D6MUaIDLYb9grXSkAFdiVMGwQFANG7Qru`FS0f0oY)2 zG4%j$f;P#)1j=AxWaz+z(ZdkNl9Q{ktDC8tIR>kMa!g>Z_*?$0&40=xK%SGmv5UE> ztD^&0E(GPA{?RrSSof!GOus={dsA0iARCmC1##*>+GPUqA6d-!T|JE5&0SorF%3h{ zegM$>kGB6QkLmY4M^l&k#@6=%(1&nP9tW($$Pj~GfP)D4%$vmLzJ}oaJ$8(3H*0%v z+!%eFGkpNS0&9QI(-!D+j6X3%08oK^%uErSwF+QE&-@4{`_2C?!vNaC%-e4nSx}!1 zWMF)97cBpmF!pfI?Ew&y|1$nZsRA>JAl07dw7(%Rd5#&+@%~?Ys&mKw;ftSRrgM4S zb1ZO@8_kt=!^Pr04(U&-r6iqPZ0M-ipre~fOKJ!EmdhE|tP@QZ zE8j;l$JS(51He7UvJ2*GHl{Z7KGu95(6?1;R zed$Lc6!9e<|DC6|H|d7C!Pm5`wlVt&4&`reuXoo3uxv3Fe@_(LR;B$J5wX~InQ)i- z@syAE7x`}srh9p28e`kzG&lCgRbDmc3jNX&5icU8IY@clLv_gShWzv$J*si!qnX+y z)%=40I3bOk;N*kX%Bl?RX@IAq_wri5E-)dY|IlDA7<=O~RGUb-X11N_8fRo>=8e4> zSxJ?a(ncoLPUg87#mWGRn~yI>1V#t_JmfjXa!`Xfrpzyx-BgcN>!@3-_vg?E<`jtG zi8TdK29R|-`_8HF)27Or`+*L!w>WGA`x7n^CmK983CP%YKUH@~Vs?y~uSX@bw_v@$ z#Gk^KgqxfKOMQUT<+AXAa&@=MAg$Pgc1Th#T~R*%O-n@$b4CNp)o7U*FCY_+b?T1u zP;f8y;g{Bc=8;dSisz^C)b#v-hyjOHrAm*EAr7hgT5{25wlUmWOwgjZsl zIyDT;tUdl{sJ0&3Q2ln+a6>J3k8Bf%BF?wK@7w1KUyb!XKh%%vK#6>@6HUm@&j}#; zT0v_cJNooosn+ump`p^-EwKw zrXFG)=9F zBVq;3cso-1PEKEHzqoP~RkdObJ!>=*+l>gN$k5}#lNFnoHCyL#^9d)#*j}Zc$|^>- zI9B%Q@CcS;#uLJX_^Wej^Rb5s_qY=$zkbX&oO|+MZW6Of{0s_7n2J9-EWU=2FriK? z9eSN+u2tJ%-Se^Mw2kJyLrap6cjf!=4PPC!Xu4h}zLe}^X9p+N*u}hd<4CGS0kmtP zy+KHT-cq&Q7czq|k^_8$x379ctd6U`>6v7&De-pWZ(oG|IxIuOK9Wslzx=&mF=ru$ zFzc3y_x9OAzyv@5RoUMgncMmPbGEMCp!R112ynBf^<$L5D?2+&|2O@I|I~ko(Fb>R zA}oOJiw}~l84Dmfvwm)$$P)lA^9%7KMfj0oV)u~}re^={-%kK26U21f_Y!9R^Tjzk zb$tCHU@q$-fWrEFANq*}OaeeB0=O=VLR?1-B2b9tPDGF|A`;T%d)Ut-+O`! ze!+gByxsxb_Oewb3%$Lvc9tY0LCp*(0&I0Y;)NEJ000H+S+XI8K&QBN2QV38ChNpv zh5hgTDV<$VAON%PpKbfE@vEH+xE=%eXCwc&{xNu90f6k;sK80^#fT7Nj%+4kY+~R( z7Ju1a^U(+ZC;$)yA1nY900SNHDNtW0a8yDBqYBbr_Lpga5S>{<9#rKF1RkY%hxyUT zYrRy*M+YR>&ZJ(I0gR2W%pIIJ*FOl%co{dVo z$6JSmbsTPsW=kAXqpb~?l#xmGWbuasUQu%--3z}G*-^ZQslKBK{0Zh&@Pj+rq)kCQ1kYfsNtj_6K74V7!!B=xM`iL{A6iS4L}ioZ>{Wv zaq0=y51sgTzDE!C5}v(--ULRWTMP@U5VMQKwh)<%Op8F(g{@UU`@$9)c;MYK{c6a_ z!$YcmbKtJoS3DP;r;te+AQrMu%jCiI`|>H?bj*Yx3Q|PiiV# z#dkL#u6ibCU^OE@X%l;gwUQ=zEVtMljTcr5Sm4#<3tHh(tB<%%r;jwHwxcWSMtakI zHxX&+3#$mLoCnk;oumwWrfrsQq$_?TB@7%%3za1m_4V6XEWuxf`!2yf6P)WmcbPwm zK_=hqzki=Y^)hu>*L4EZA>svs#cpD+Ba>mG{-aD=+z|J{MGv(m{O!9RJuC{EUGS)L zxP(KvW=f_V`rK8kUzF27(^xuaE6|`i2uRTouTvj=AXsWU(-yz(q_$^y1v&CXO~)N^ zBO%ijL7T83h`1WFCWxq9wUa7XmZ)BR%iy;`635_NlbW?W$6Ii}4$(uX3yo1a;(Oof z>>OU)MC$mkq0PdoPcpmq;uBHDZ|lp@V( zit{1XGVQ#N0#==eao`-d zvaT<%Ds+Wkh*fkV@d+xnXd(t4>a`zw!4h;NJ(cFURZ8A>bGtp#S#OY>Pm%!FqsZN} zW%>J_Bw~159Y}sqOnwP?Va4FPo4ns}+N_wDI641L=cZ5vVN;a7P;*>gy-hd7;vVKk zA4s7Nk%mY@ju(8=i*ptW^-3uDWGrbGX&fDd{Z4{Z47-~(#a{iqCcO8l_ZR#JbIvnv z%?;Q!!n6ZoO_+y2rB(l9FTI|mTFT|#Bw3t?uIlU~w(D`p&f8(XnDuV-3}`J&|D=5> zarddL@pqI4?`V|DPMD{rT9$rt#(=;f^L6r5m1C-qiqmNtxyZqX;^J&9RD|_XoXIv# z)k7iKbO;3@bwy@2@63c{lw_!(*;6CK9IlR)J0aPrR}ZZnu81-#Nkm_;3Jikb(v+C^ zp|j{W4^RT%R}EE=AsdM~cJNk9FIrvhoYoasHB358OXX6CK9?0Q!?AC+mQ{Wl<2#64Y zP=e5QMTLM?v-fiT%-@}Oj`Shw;@Emhtc?mDOAd@7!U@DW21&+}i2YOAFWYNVCaumsJHzeq>P&X*W=m#S$o& z7%g3yD#%JK3GiBo_>{)y7%O5i8>PZ|$A5W(CgXbEo2Jn>!&7>)aoV4XUZ>F)38VKr ztpt`>U!;6O*-2ev>D=dpKbeWMMLpsj-7d&r(#Bm*HFLfKx{RMFn!gm;-nYutUGC}E z-#9O_YsMTTN3zLc>{DgW$`W_)D56noKH>h%HhZwvLcB=zBg2w_Q};>u6~olkVOgos=g20~AjKgZP%mv-(`h7cO)sJgxtm~u$}Zh1s~8tBrv zs%cvvVE-NS9s=F4EJM=nDh3ok7iBDdcNLqRMm@APHrfSQdTH;nexZ7?VJuHDYdeG4 zfP{{1y+E1B?Dmd=)_v+G{oqkik6bNJ^wM-7qWeoi^{%`EZdBvIgbm|O+C-UMnw1Et zCnu9;CzIYMlRF*hGP_6RdsI7#hh}pOJG)e_`IENswl~r74ecThbp~^_%l%+(JL@u0 zyIktrlV&iNI96;?XHl{e+n_H=^CD2JU^c~8y^hCGz0TXUyHR3!F4YArH@LtkA9bhP znoHdtOLbX(;n&wU<+L<#>}kvNqf5}W`g+@bPQ1XE9a1fARi{`2t84AB?z^LR6In|{ zWV=Q*h&OoJTQYd?hqS$&vx}~Hi05 zy|u>Ea5zpYR#3mDN{q`YYjR!@W!|VwJQn&98;-wVp_aV8qJ<(zY&W9aujyB*fLCWmYR!MVwS9R~AKaam;>M*_|nINszZ-d2mm*UjWN^Fi| zlo^n(oK(H9vzE;`SjQ3l$xW*!XuVo<2wU<)Tjv)GLyJ>|h6#N>bEIk)_W|!tNjzPB zGVX*z0>1-GQ5>qzyK6j{Bu!;B*ZXqT;Ovdr-L!5Ouk~)qNYP|}8iAIk$DhkNr8}M3 z?!K5PzDx0`kh0?TKBZ^r6-Od#MVTw95*PGpcWndP?p zT#yU@hnbhT8k!%iD4(uz&P&x=RpR1?%TXp#Ek?BTHw*Uq*S^Ky`Q;;mCt4=N^3vkq zh%;=i8$snsktX-KZ=Mx;bL}AaZVTZs~~)c7meZd+a+)zY0s}OQzuuH?8&@rlMbs z$6154*8?pt+N__6Lh))fegLlD-RgHZuvay!!wvh=uZ!-X@? zN4#r2m+3QmAR$UkdU6-SLi8eWBAwmmU_4hsEAkIcXNj?)g_HcvY7|uNGOFbqb0n^nMH?l%y(6$=R^ZCS=H=UG2bx|o55EQj(WsM}P>1I@mFx`7R>n=TPC30>@6Fq3;ED%sZXR2teJQ8U4{sskIJlRLUyasMmUz~GE3Jjy>mv2^gU^*O zF6w4nR{Wq(nrAga-rV=8-VDpsft%>Bm(xY+eK8hGm}z=lwMAR`_D~JeT2#Beb}_#3YTtR)eHT zk@Fe(1b?DuhT>0?uVddG)Qf+nc!f+ q`MSm^l%2=Z_RsTw#zjFksEzsj`~R3W#$W#zG3`!pUgXaHgZK{%iEs@7 literal 0 HcmV?d00001 diff --git a/meshtastic/tests/test_analysis.py b/meshtastic/tests/test_analysis.py new file mode 100644 index 0000000..ea8d6ae --- /dev/null +++ b/meshtastic/tests/test_analysis.py @@ -0,0 +1,25 @@ +"""Test analysis processing.""" + +import logging +import os +import sys + +import pytest + +from meshtastic.analysis.__main__ import main + + +@pytest.mark.unit +def test_analysis(caplog): + """Test analysis processing""" + + cur_dir = os.path.dirname(os.path.abspath(__file__)) + slog_input_dir = os.path.join(cur_dir, "slog-test-input") + + sys.argv = ["fakescriptname", "--no-server", "--slog", slog_input_dir] + + with caplog.at_level(logging.DEBUG): + logging.getLogger().propagate = True # Let our testing framework see our logs + main() + + assert "Exiting without running visualization server" in caplog.text From 2ae18c1903cfab4a2fee32f01eb9e53ac4c8d4ea Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 4 Aug 2024 12:22:57 -0700 Subject: [PATCH 159/248] Clarify documentation of position options slightly --- meshtastic/__main__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 87d23cb..2469c77 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1501,17 +1501,17 @@ def initParser(): group.add_argument( "--setalt", - help="Set device altitude in meters (allows use without GPS), and enable fixed position.", + help="Set device altitude in meters (allows use without GPS), and enable fixed position. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( "--setlat", - help="Set device latitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7.", + help="Set device latitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( "--setlon", - help="Set device longitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7.", + help="Set device longitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( From e84a3cb46843c2d675214f826bd97cb9ea48b7d6 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 4 Aug 2024 12:26:20 -0700 Subject: [PATCH 160/248] appease pylint --- meshtastic/__main__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 2469c77..f6096a7 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1501,17 +1501,20 @@ def initParser(): group.add_argument( "--setalt", - help="Set device altitude in meters (allows use without GPS), and enable fixed position. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", + help="Set device altitude in meters (allows use without GPS), and enable fixed position. " + "When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( "--setlat", - help="Set device latitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", + help="Set device latitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. " + "When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( "--setlon", - help="Set device longitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", + help="Set device longitude (allows use without GPS), and enable fixed position. Accepts a decimal value or an integer premultiplied by 1e7. " + "When providing positions with `--setlat`, `--setlon`, and `--setalt`, missing values will be set to 0.", ) group.add_argument( From 5366ddf7708c931297cc1876b3fd58bf8c367319 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 8 Aug 2024 09:43:43 -0700 Subject: [PATCH 161/248] Add/update some types to be at least as backwards-compatible as we can be --- meshtastic/analysis/__main__.py | 4 ++-- meshtastic/slog/arrow.py | 4 ++-- meshtastic/slog/slog.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/meshtastic/analysis/__main__.py b/meshtastic/analysis/__main__.py index c4d79e9..50505a6 100644 --- a/meshtastic/analysis/__main__.py +++ b/meshtastic/analysis/__main__.py @@ -2,7 +2,7 @@ import argparse import logging -from typing import cast +from typing import cast, List import dash_bootstrap_components as dbc # type: ignore[import-untyped] import numpy as np @@ -20,7 +20,7 @@ from ..slog import root_dir pd.options.mode.copy_on_write = True -def to_pmon_names(arr) -> list[str]: +def to_pmon_names(arr) -> List[str]: """Convert the power monitor state numbers to their corresponding names. arr (list): List of power monitor state numbers. diff --git a/meshtastic/slog/arrow.py b/meshtastic/slog/arrow.py index 4bb2e78..74fb5b5 100644 --- a/meshtastic/slog/arrow.py +++ b/meshtastic/slog/arrow.py @@ -3,7 +3,7 @@ import logging import threading import os -from typing import Optional +from typing import Optional, List import pyarrow as pa from pyarrow import feather @@ -20,7 +20,7 @@ class ArrowWriter: file_name (str): The name of the file to write to. """ self.sink = pa.OSFile(file_name, "wb") # type: ignore - self.new_rows: list[dict] = [] + self.new_rows: List[dict] = [] self.schema: Optional[pa.Schema] = None # haven't yet learned the schema self.writer: Optional[pa.RecordBatchStreamWriter] = None self._lock = threading.Condition() # Ensure only one thread writes at a time diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 326bac6..6b09e4b 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -10,7 +10,7 @@ import time from dataclasses import dataclass from datetime import datetime from functools import reduce -from typing import Optional +from typing import Optional, List, Tuple import parse # type: ignore[import-untyped] import platformdirs @@ -39,10 +39,10 @@ class LogDef: """Log definition.""" code: str # i.e. PM or B or whatever... see meshtastic slog documentation - fields: list[tuple[str, pa.DataType]] # A list of field names and their arrow types + fields: List[Tuple[str, pa.DataType]] # A list of field names and their arrow types format: parse.Parser # A format string that can be used to parse the arguments - def __init__(self, code: str, fields: list[tuple[str, pa.DataType]]) -> None: + def __init__(self, code: str, fields: List[Tuple[str, pa.DataType]]) -> None: """Initialize the LogDef object. code (str): The code. @@ -93,7 +93,7 @@ class PowerLogger: ) self.thread.start() - def store_current_reading(self, now: datetime | None = None) -> None: + def store_current_reading(self, now: Optional[datetime] = None) -> None: """Store current power measurement.""" if now is None: now = datetime.now() @@ -133,7 +133,7 @@ class StructuredLogger: self, client: MeshInterface, dir_path: str, - power_logger: PowerLogger | None = None, + power_logger: Optional[PowerLogger] = None, include_raw=True, ) -> None: """Initialize the StructuredLogger object. From 72de803195f83d8f89e860645e2adf02a8a47bec Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 11 Aug 2024 10:08:40 -0700 Subject: [PATCH 162/248] Attempt to make powermon stuff optional, hopefully allowing pypi release --- meshtastic/__main__.py | 47 +++++++++++++++++++++++++++--------------- poetry.lock | 10 +++------ pyproject.toml | 9 ++++++-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index d879aac..fc39da2 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -23,13 +23,19 @@ import meshtastic.util from meshtastic import BROADCAST_ADDR, mt_config, remote_hardware from meshtastic.ble_interface import BLEInterface from meshtastic.mesh_interface import MeshInterface -from meshtastic.powermon import ( - PowerMeter, - PowerStress, - PPK2PowerSupply, - RidenPowerSupply, - SimPowerSupply, -) +try: + from meshtastic.powermon import ( + PowerMeter, + PowerStress, + PPK2PowerSupply, + RidenPowerSupply, + SimPowerSupply, + ) + have_powermon = True + powermon_exception = None +except ImportError as e: + have_powermon = False + powermon_exception = e from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 from meshtastic.slog import LogSet from meshtastic.version import get_active_version @@ -895,16 +901,22 @@ def onConnected(interface): # we need to keep a reference to the logset so it doesn't get GCed early if args.slog or args.power_stress: - # Setup loggers - global meter # pylint: disable=global-variable-not-assigned - log_set = LogSet( - interface, args.slog if args.slog != "default" else None, meter - ) + if have_powermon: + # Setup loggers + global meter # pylint: disable=global-variable-not-assigned + log_set = LogSet( + interface, args.slog if args.slog != "default" else None, meter + ) + + if args.power_stress: + stress = PowerStress(interface) + stress.run() + closeNow = True # exit immediately after stress test + else: + meshtastic.util.our_exit("The powermon module could not be loaded. " + "You may need to run `poetry install --with powermon`. " + "Import Error was: " + powermon_exception) - if args.power_stress: - stress = PowerStress(interface) - stress.run() - closeNow = True # exit immediately after stress test if args.listen: closeNow = False @@ -1101,7 +1113,8 @@ def common(): meshtastic.util.support_info() meshtastic.util.our_exit("", 0) - create_power_meter() + if have_powermon: + create_power_meter() if args.ch_index is not None: channelIndex = int(args.ch_index) diff --git a/poetry.lock b/poetry.lock index 63c3267..27425c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "altgraph" @@ -1902,29 +1902,24 @@ files = [ {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, - {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, - {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, - {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, - {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, - {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, ] @@ -3151,6 +3146,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -4161,4 +4157,4 @@ tunnel = ["pytap2"] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "c696888a3c3c82fb8908d8ddf8c917abba741c00b6f1e21ee0a489dd1fbff5da" +content-hash = "66b7938a3260be05efac7e73d4dd336100e898d092951e644497f5d944fa8278" diff --git a/pyproject.toml b/pyproject.toml index 3f87d86..681086b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,9 +21,7 @@ pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" packaging = "^24.0" -riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } parse = "^1.20.2" -ppk2-api = "^0.9.2" pyarrow = "^16.1.0" platformdirs = "^4.2.2" print-color = "^0.4.6" @@ -50,6 +48,13 @@ types-pyyaml = "^6.0.12.20240311" pyarrow-stubs = "^10.0.1.7" pandas-stubs = "^2.2.2.240603" +[tool.poetry.group.powermon] +optional = true + +[tool.poetry.group.powermon.dependencies] +riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } +ppk2-api = "^0.9.2" + # If you are doing power analysis you might want these extra devtools [tool.poetry.group.analysis] optional = true From b8c0a62b27e1f24af562a74c6709dfc2cd6a48e3 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 11 Aug 2024 10:11:35 -0700 Subject: [PATCH 163/248] Add powermon group to ci install --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c01798b..1de0ebc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: pip3 install poetry - name: Install meshtastic from local run: | - poetry install --all-extras --with dev + poetry install --all-extras --with dev,powermon poetry run meshtastic --version - name: Run pylint run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$" From 6757f5cdb51cf596c69cca704ec7067bf6155297 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 11 Aug 2024 10:16:22 -0700 Subject: [PATCH 164/248] slog depends on powermon, so move it within the optional block as well --- meshtastic/__main__.py | 2 +- poetry.lock | 2 +- pyproject.toml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fc39da2..a433bf3 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -31,13 +31,13 @@ try: RidenPowerSupply, SimPowerSupply, ) + from meshtastic.slog import LogSet have_powermon = True powermon_exception = None except ImportError as e: have_powermon = False powermon_exception = e from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 -from meshtastic.slog import LogSet from meshtastic.version import get_active_version meter: Optional[PowerMeter] = None diff --git a/poetry.lock b/poetry.lock index 27425c3..28373e0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4157,4 +4157,4 @@ tunnel = ["pytap2"] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.13" -content-hash = "66b7938a3260be05efac7e73d4dd336100e898d092951e644497f5d944fa8278" +content-hash = "aa66d6081174b6f17b907b29c6ef0e5cc7088696154cf1f40ce99eb1b4c172f3" diff --git a/pyproject.toml b/pyproject.toml index 681086b..2326b04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,9 +21,6 @@ pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = "^0.21.1" packaging = "^24.0" -parse = "^1.20.2" -pyarrow = "^16.1.0" -platformdirs = "^4.2.2" print-color = "^0.4.6" dash = { version = "^2.17.1", optional = true } pytap2 = { version = "^2.3.0", optional = true } @@ -54,6 +51,9 @@ optional = true [tool.poetry.group.powermon.dependencies] riden = { git = "https://github.com/geeksville/riden.git#1.2.1" } ppk2-api = "^0.9.2" +parse = "^1.20.2" +pyarrow = "^16.1.0" +platformdirs = "^4.2.2" # If you are doing power analysis you might want these extra devtools [tool.poetry.group.analysis] From 40d03a6ea19ee2112a2a9759337217577b069921 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 11 Aug 2024 10:19:38 -0700 Subject: [PATCH 165/248] mess with more stuff to try to make powermon optional --- meshtastic/__main__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index a433bf3..e7886e6 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -34,15 +34,14 @@ try: from meshtastic.slog import LogSet have_powermon = True powermon_exception = None + meter: Optional[PowerMeter] = None except ImportError as e: have_powermon = False powermon_exception = e + meter = None from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 from meshtastic.version import get_active_version -meter: Optional[PowerMeter] = None - - def onReceive(packet, interface): """Callback invoked when a packet arrives""" args = mt_config.args @@ -897,7 +896,7 @@ def onConnected(interface): qr = pyqrcode.create(url) print(qr.terminal()) - log_set: Optional[LogSet] = None # type: ignore[annotation-unchecked] + log_set: Optional = None # type: ignore[annotation-unchecked] # we need to keep a reference to the logset so it doesn't get GCed early if args.slog or args.power_stress: From a8d86dee2db53c60e701b17b37f0943dfb0e19c3 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 11 Aug 2024 17:22:31 +0000 Subject: [PATCH 166/248] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2326b04..167e194 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.14" +version = "2.3.15" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From d57186d1e4311d7fad0b252c34e601f52885f8e3 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:07:35 -0700 Subject: [PATCH 167/248] protobufs: v2.4.0 --- meshtastic/protobuf/config_pb2.py | 22 ++++++------ meshtastic/protobuf/config_pb2.pyi | 8 ++++- meshtastic/protobuf/module_config_pb2.py | 44 +++++++++++------------ meshtastic/protobuf/module_config_pb2.pyi | 12 ++++++- meshtastic/protobuf/telemetry_pb2.py | 24 ++++++------- meshtastic/protobuf/telemetry_pb2.pyi | 14 +++++++- protobufs | 2 +- 7 files changed, 77 insertions(+), 49 deletions(-) diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index 04b4097..95492a4 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xc3#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa7\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xc2\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xd6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\x1e\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xdc#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa7\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xdb\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xd6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\x1e\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -28,7 +28,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=4605 + _globals['_CONFIG']._serialized_end=4630 _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 _globals['_CONFIG_DEVICECONFIG']._serialized_end=1176 _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 @@ -62,13 +62,13 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3346 _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3532 _globals['_CONFIG_LORACONFIG']._serialized_start=3535 - _globals['_CONFIG_LORACONFIG']._serialized_end=4369 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4013 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4218 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4221 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4369 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4372 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4586 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4530 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4586 + _globals['_CONFIG_LORACONFIG']._serialized_end=4394 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4038 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4243 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4246 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4394 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4397 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4611 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4555 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4611 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 2a5857d..d966d2c 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -1378,6 +1378,7 @@ class Config(google.protobuf.message.Message): OVERRIDE_DUTY_CYCLE_FIELD_NUMBER: builtins.int SX126X_RX_BOOSTED_GAIN_FIELD_NUMBER: builtins.int OVERRIDE_FREQUENCY_FIELD_NUMBER: builtins.int + PA_FAN_DISABLED_FIELD_NUMBER: builtins.int IGNORE_INCOMING_FIELD_NUMBER: builtins.int IGNORE_MQTT_FIELD_NUMBER: builtins.int use_preset: builtins.bool @@ -1465,6 +1466,10 @@ class Config(google.protobuf.message.Message): Please respect your local laws and regulations. If you are a HAM, make sure you enable HAM mode and turn off encryption. """ + pa_fan_disabled: builtins.bool + """ + If true, disable the build-in PA FAN using pin define in RF95_FAN_EN. + """ ignore_mqtt: builtins.bool """ If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. @@ -1494,10 +1499,11 @@ class Config(google.protobuf.message.Message): override_duty_cycle: builtins.bool = ..., sx126x_rx_boosted_gain: builtins.bool = ..., override_frequency: builtins.float = ..., + pa_fan_disabled: builtins.bool = ..., ignore_incoming: collections.abc.Iterable[builtins.int] | None = ..., ignore_mqtt: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... + def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "pa_fan_disabled", b"pa_fan_disabled", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... @typing.final class BluetoothConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/module_config_pb2.py b/meshtastic/protobuf/module_config_pb2.py index b75bbfa..de20ac0 100644 --- a/meshtastic/protobuf/module_config_pb2.py +++ b/meshtastic/protobuf/module_config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\"\x90$\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1aN\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1a>\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x1a\xd2\x01\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12 \n\x18\x64\x65tection_triggered_high\x18\x07 \x01(\x08\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xf6\x04\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"U\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x84\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x1a@\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x1a\xe6\x02\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x1a\xf1\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x0f\n\x07\x65nabled\x18\t \x01(\x08\x12\x1a\n\x12\x61llow_input_source\x18\n \x01(\t\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\rB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42g\n\x13\x63om.geeksville.meshB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\"\xad$\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1aN\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1a>\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x1a\xd2\x01\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12 \n\x18\x64\x65tection_triggered_high\x18\x07 \x01(\x08\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\x80\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"_\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1a@\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x1a\xe6\x02\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x1a\xf1\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x0f\n\x07\x65nabled\x18\t \x01(\x08\x12\x1a\n\x12\x61llow_input_source\x18\n \x01(\t\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\rB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42g\n\x13\x63om.geeksville.meshB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,10 +21,10 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.module_ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\022ModuleConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=4802 - _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=4875 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=4831 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=4904 _globals['_MODULECONFIG']._serialized_start=65 - _globals['_MODULECONFIG']._serialized_end=4689 + _globals['_MODULECONFIG']._serialized_end=4718 _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1080 _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1393 _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1395 @@ -42,25 +42,25 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2262 _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=2380 _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=2383 - _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3013 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3023 _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=2660 _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=2926 _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=2928 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3013 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3016 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=3377 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=3380 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=3512 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=3514 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=3578 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=3581 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=3939 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=3942 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=4567 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=4468 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=4567 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=4569 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=4670 - _globals['_REMOTEHARDWAREPIN']._serialized_start=4691 - _globals['_REMOTEHARDWAREPIN']._serialized_end=4800 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3023 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3026 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=3387 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=3390 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=3541 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=3543 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=3607 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=3610 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=3968 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=3971 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=4596 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=4497 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=4596 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=4598 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=4699 + _globals['_REMOTEHARDWAREPIN']._serialized_start=4720 + _globals['_REMOTEHARDWAREPIN']._serialized_end=4829 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/module_config_pb2.pyi b/meshtastic/protobuf/module_config_pb2.pyi index eb4f986..5bc30ad 100644 --- a/meshtastic/protobuf/module_config_pb2.pyi +++ b/meshtastic/protobuf/module_config_pb2.pyi @@ -503,6 +503,8 @@ class ModuleConfig(google.protobuf.message.Message): NMEA: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 4 CALTOPO: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 5 """NMEA messages specifically tailored for CalTopo""" + WS85: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 6 + """Ecowitt WS85 weather station""" class Serial_Mode(_Serial_Mode, metaclass=_Serial_ModeEnumTypeWrapper): """ @@ -516,6 +518,8 @@ class ModuleConfig(google.protobuf.message.Message): NMEA: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 4 CALTOPO: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 5 """NMEA messages specifically tailored for CalTopo""" + WS85: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 6 + """Ecowitt WS85 weather station""" ENABLED_FIELD_NUMBER: builtins.int ECHO_FIELD_NUMBER: builtins.int @@ -701,6 +705,7 @@ class ModuleConfig(google.protobuf.message.Message): RECORDS_FIELD_NUMBER: builtins.int HISTORY_RETURN_MAX_FIELD_NUMBER: builtins.int HISTORY_RETURN_WINDOW_FIELD_NUMBER: builtins.int + IS_SERVER_FIELD_NUMBER: builtins.int enabled: builtins.bool """ Enable the Store and Forward Module @@ -721,6 +726,10 @@ class ModuleConfig(google.protobuf.message.Message): """ TODO: REPLACE """ + is_server: builtins.bool + """ + Set to true to let this node act as a server that stores received messages and resends them upon request. + """ def __init__( self, *, @@ -729,8 +738,9 @@ class ModuleConfig(google.protobuf.message.Message): records: builtins.int = ..., history_return_max: builtins.int = ..., history_return_window: builtins.int = ..., + is_server: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "heartbeat", b"heartbeat", "history_return_max", b"history_return_max", "history_return_window", b"history_return_window", "records", b"records"]) -> None: ... + def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "heartbeat", b"heartbeat", "history_return_max", b"history_return_max", "history_return_window", b"history_return_window", "is_server", b"is_server", "records", b"records"]) -> None: ... @typing.final class RangeTestConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 5a1188d..14b5351 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xb6\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xdc\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\x12\x11\n\twind_gust\x18\x10 \x01(\x02\x12\x11\n\twind_lull\x18\x11 \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,18 +21,18 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemet if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=1339 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=1701 + _globals['_TELEMETRYSENSORTYPE']._serialized_start=1377 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=1739 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=190 _globals['_ENVIRONMENTMETRICS']._serialized_start=193 - _globals['_ENVIRONMENTMETRICS']._serialized_end=503 - _globals['_POWERMETRICS']._serialized_start=506 - _globals['_POWERMETRICS']._serialized_end=646 - _globals['_AIRQUALITYMETRICS']._serialized_start=649 - _globals['_AIRQUALITYMETRICS']._serialized_end=968 - _globals['_TELEMETRY']._serialized_start=971 - _globals['_TELEMETRY']._serialized_end=1272 - _globals['_NAU7802CONFIG']._serialized_start=1274 - _globals['_NAU7802CONFIG']._serialized_end=1336 + _globals['_ENVIRONMENTMETRICS']._serialized_end=541 + _globals['_POWERMETRICS']._serialized_start=544 + _globals['_POWERMETRICS']._serialized_end=684 + _globals['_AIRQUALITYMETRICS']._serialized_start=687 + _globals['_AIRQUALITYMETRICS']._serialized_end=1006 + _globals['_TELEMETRY']._serialized_start=1009 + _globals['_TELEMETRY']._serialized_end=1310 + _globals['_NAU7802CONFIG']._serialized_start=1312 + _globals['_NAU7802CONFIG']._serialized_end=1374 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index fb0f4dd..83334ec 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -308,6 +308,8 @@ class EnvironmentMetrics(google.protobuf.message.Message): WIND_DIRECTION_FIELD_NUMBER: builtins.int WIND_SPEED_FIELD_NUMBER: builtins.int WEIGHT_FIELD_NUMBER: builtins.int + WIND_GUST_FIELD_NUMBER: builtins.int + WIND_LULL_FIELD_NUMBER: builtins.int temperature: builtins.float """ Temperature measured @@ -370,6 +372,14 @@ class EnvironmentMetrics(google.protobuf.message.Message): """ Weight in KG """ + wind_gust: builtins.float + """ + Wind gust in m/s + """ + wind_lull: builtins.float + """ + Wind lull in m/s + """ def __init__( self, *, @@ -388,8 +398,10 @@ class EnvironmentMetrics(google.protobuf.message.Message): wind_direction: builtins.int = ..., wind_speed: builtins.float = ..., weight: builtins.float = ..., + wind_gust: builtins.float = ..., + wind_lull: builtins.float = ..., ) -> None: ... - 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", "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_speed", b"wind_speed"]) -> None: ... + 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", "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: ... global___EnvironmentMetrics = EnvironmentMetrics diff --git a/protobufs b/protobufs index 1198b7d..10494bf 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 1198b7dbabf9768cb0143d2897707b4c7a51a5da +Subproject commit 10494bf328ac051fc4add9ddeb677eebf337b531 From 28d8355547c27e471d8855cc49b990450db42498 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:11:12 -0700 Subject: [PATCH 168/248] Use poetry version minor, to revert after 2.4.0 release --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 889bb3b..5b2c489 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Bump version run: >- - poetry version patch + poetry version minor - name: Commit updated version. id: commit_updated From c59583e4bd2eec58f7455d648c0f5a982b20734f Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:17:58 -0700 Subject: [PATCH 169/248] Make version-bump commit include the version being bumped to --- .github/workflows/release.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b2c489..d93fda2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,6 +28,11 @@ jobs: run: >- poetry version minor + - name: Get version + id: get_version + run: >- + poetry version --short | sed 's/^/::set-output name=version::/' + - name: Commit updated version. id: commit_updated run: | @@ -35,14 +40,9 @@ jobs: git config --global user.email 'bot@noreply.github.com' git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} git add pyproject.toml - git commit -m "bump version" && git push || echo "No changes to commit" + git commit -m "bump version to ${{ steps.get_version.outputs.version }}" && git push || echo "No changes to commit" git log -n 1 --pretty=format:"%H" | tail -n 1 | awk '{print "::set-output name=sha::"$0}' - - name: Get version - id: get_version - run: >- - poetry version --short | sed 's/^/::set-output name=version::/' - - name: Create GitHub release uses: actions/create-release@v1 id: create_release From d5f732263a2c76a7b51ecc791e8c7a68ecfde51d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:18:48 -0700 Subject: [PATCH 170/248] set alpha 2.4.0a0 version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 167e194..364c2dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.3.15" +version = "2.4.0a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 4ad776f219a1edfc57a4c2323ddaa50ecd5d7a67 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:20:10 -0700 Subject: [PATCH 171/248] revert poetry version minor change -- with alpha version set, it's unnecessary --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d93fda2..e780ac1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Bump version run: >- - poetry version minor + poetry version patch - name: Get version id: get_version From 3335b3d6514f4f52eb7004abfcc66d30bc4172aa Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 22 Aug 2024 02:23:53 +0000 Subject: [PATCH 172/248] bump version to 2.4.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 364c2dd..ea8b8b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.0a0" +version = "2.4.0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From abb00251c090718b9b76b7bb538aed837d91bdb3 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:52:56 -0700 Subject: [PATCH 173/248] protobufs: v2.4.1 --- meshtastic/protobuf/mesh_pb2.py | 12 ++++++------ meshtastic/protobuf/mesh_pb2.pyi | 16 ++++++++++++++++ protobufs | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 3d46744..6016cdd 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xa3\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xd0\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,11 +32,11 @@ if _descriptor._USE_C_DESCRIPTORS == False: _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' _globals['_HARDWAREMODEL']._serialized_start=5544 - _globals['_HARDWAREMODEL']._serialized_end=6859 - _globals['_CONSTANTS']._serialized_start=6861 - _globals['_CONSTANTS']._serialized_end=6905 - _globals['_CRITICALERRORCODE']._serialized_start=6908 - _globals['_CRITICALERRORCODE']._serialized_end=7146 + _globals['_HARDWAREMODEL']._serialized_end=6904 + _globals['_CONSTANTS']._serialized_start=6906 + _globals['_CONSTANTS']._serialized_end=6950 + _globals['_CRITICALERRORCODE']._serialized_start=6953 + _globals['_CRITICALERRORCODE']._serialized_end=7191 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 4fed322..2e53c48 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -324,6 +324,14 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design, specifically adapted for the Meshtatic project """ + SENSECAP_INDICATOR: _HardwareModel.ValueType # 70 + """ + Sensecap Indicator from Seeed Studio. ESP32-S3 device with TFT and RP2040 coprocessor + """ + TRACKER_T1000_E: _HardwareModel.ValueType # 71 + """ + Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -632,6 +640,14 @@ HELTEC_MESH_NODE_T114: HardwareModel.ValueType # 69 Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design, specifically adapted for the Meshtatic project """ +SENSECAP_INDICATOR: HardwareModel.ValueType # 70 +""" +Sensecap Indicator from Seeed Studio. ESP32-S3 device with TFT and RP2040 coprocessor +""" +TRACKER_T1000_E: HardwareModel.ValueType # 71 +""" +Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/protobufs b/protobufs index 10494bf..b1a79d5 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 10494bf328ac051fc4add9ddeb677eebf337b531 +Subproject commit b1a79d5db00f6aeeb0bbae156e8939e146c95299 From 740f0f09612dd367f478798330dd2770077f817d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 19:53:23 -0700 Subject: [PATCH 174/248] set prerelease version to match protobufs --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ea8b8b8..1767bda 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.0" +version = "2.4.1a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From abf9e96d3d06da06430e7591d6875a176ca0a14e Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 20:07:12 -0700 Subject: [PATCH 175/248] Set release tag to the version update commit sha, not the pre-update one --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e780ac1..4bb2bd6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,6 +52,7 @@ jobs: prerelease: true release_name: Meshtastic Python ${{ steps.get_version.outputs.version }} tag_name: ${{ steps.get_version.outputs.version }} + commitish: ${{ steps.commit_updated.outputs.sha }} body: | Autogenerated by github action, developer should edit as required before publishing... env: From 48987c38e245bb36205282e479f6b1343810cb8b Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 21:55:43 -0700 Subject: [PATCH 176/248] set alpha version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1767bda..a8366ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.1a0" +version = "2.5.0a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From bb6f51eb43d6270d579972ea3554f6f392526f25 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 21:56:01 -0700 Subject: [PATCH 177/248] protobufs: 2.5 (in progress, untagged) --- meshtastic/protobuf/admin_pb2.py | 20 +- meshtastic/protobuf/admin_pb2.pyi | 47 +++- meshtastic/protobuf/config_pb2.py | 102 ++++---- meshtastic/protobuf/config_pb2.pyi | 106 ++++++++- meshtastic/protobuf/deviceonly_pb2.py | 31 ++- meshtastic/protobuf/deviceonly_pb2.pyi | 66 +++++- meshtastic/protobuf/localonly_pb2.py | 8 +- meshtastic/protobuf/localonly_pb2.pyi | 12 +- meshtastic/protobuf/mesh_pb2.py | 134 +++++------ meshtastic/protobuf/mesh_pb2.pyi | 226 ++++++++++++++++-- meshtastic/protobuf/module_config_pb2.pyi | 2 +- meshtastic/protobuf/portnums_pb2.pyi | 4 +- meshtastic/protobuf/telemetry_pb2.py | 30 +-- meshtastic/protobuf/telemetry_pb2.pyi | 274 ++++++++++++++++++---- protobufs | 2 +- 15 files changed, 829 insertions(+), 235 deletions(-) diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index c002b8f..d646337 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -18,7 +18,7 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xea\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xef\x13\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\xc1\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\x12\x13\n\x0fSECURITY_CONFIG\x10\x07\x12\x15\n\x11SESSIONKEY_CONFIG\x10\x08\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,13 +27,13 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_ADMINMESSAGE']._serialized_start=244 - _globals['_ADMINMESSAGE']._serialized_end=2654 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2168 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2317 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2320 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2635 - _globals['_HAMPARAMETERS']._serialized_start=2656 - _globals['_HAMPARAMETERS']._serialized_end=2747 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2749 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2860 + _globals['_ADMINMESSAGE']._serialized_end=2787 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2257 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2450 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2453 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2768 + _globals['_HAMPARAMETERS']._serialized_start=2789 + _globals['_HAMPARAMETERS']._serialized_end=2880 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2882 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2993 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index 0840385..2f8cc09 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -68,6 +68,12 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + SECURITY_CONFIG: AdminMessage._ConfigType.ValueType # 7 + """ + TODO: REPLACE + """ + SESSIONKEY_CONFIG: AdminMessage._ConfigType.ValueType # 8 + """""" class ConfigType(_ConfigType, metaclass=_ConfigTypeEnumTypeWrapper): """ @@ -102,6 +108,12 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + SECURITY_CONFIG: AdminMessage.ConfigType.ValueType # 7 + """ + TODO: REPLACE + """ + SESSIONKEY_CONFIG: AdminMessage.ConfigType.ValueType # 8 + """""" class _ModuleConfigType: ValueType = typing.NewType("ValueType", builtins.int) @@ -220,6 +232,7 @@ class AdminMessage(google.protobuf.message.Message): TODO: REPLACE """ + SESSION_PASSKEY_FIELD_NUMBER: builtins.int GET_CHANNEL_REQUEST_FIELD_NUMBER: builtins.int GET_CHANNEL_RESPONSE_FIELD_NUMBER: builtins.int GET_OWNER_REQUEST_FIELD_NUMBER: builtins.int @@ -253,14 +266,22 @@ class AdminMessage(google.protobuf.message.Message): REMOVE_FAVORITE_NODE_FIELD_NUMBER: builtins.int SET_FIXED_POSITION_FIELD_NUMBER: builtins.int REMOVE_FIXED_POSITION_FIELD_NUMBER: builtins.int + SET_TIME_ONLY_FIELD_NUMBER: builtins.int BEGIN_EDIT_SETTINGS_FIELD_NUMBER: builtins.int COMMIT_EDIT_SETTINGS_FIELD_NUMBER: builtins.int + FACTORY_RESET_DEVICE_FIELD_NUMBER: builtins.int REBOOT_OTA_SECONDS_FIELD_NUMBER: builtins.int EXIT_SIMULATOR_FIELD_NUMBER: builtins.int REBOOT_SECONDS_FIELD_NUMBER: builtins.int SHUTDOWN_SECONDS_FIELD_NUMBER: builtins.int - FACTORY_RESET_FIELD_NUMBER: builtins.int + FACTORY_RESET_CONFIG_FIELD_NUMBER: builtins.int NODEDB_RESET_FIELD_NUMBER: builtins.int + session_passkey: builtins.bytes + """ + The node generates this key and sends it with any get_x_response packets. + The client MUST include the same key with any set_x commands. Key expires after 300 seconds. + Prevents replay attacks for admin messages. + """ get_channel_request: builtins.int """ Send the specified channel in the response to this message @@ -343,6 +364,11 @@ class AdminMessage(google.protobuf.message.Message): """ Clear fixed position coordinates and then set position.fixed_position = false """ + set_time_only: builtins.int + """ + Set time only on the node + Convenience method to set the time on the node (as Net quality) without any other position data + """ begin_edit_settings: builtins.bool """ Begins an edit transaction for config, module config, owner, and channel settings changes @@ -352,6 +378,10 @@ class AdminMessage(google.protobuf.message.Message): """ Commits an open transaction for any edits made to config, module config, owner, and channel settings """ + factory_reset_device: builtins.int + """ + Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. + """ reboot_ota_seconds: builtins.int """ Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) @@ -370,9 +400,9 @@ class AdminMessage(google.protobuf.message.Message): """ Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) """ - factory_reset: builtins.int + factory_reset_config: builtins.int """ - Tell the node to factory reset, all device settings will be returned to factory defaults. + Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. """ nodedb_reset: builtins.int """ @@ -463,6 +493,7 @@ class AdminMessage(google.protobuf.message.Message): def __init__( self, *, + session_passkey: builtins.bytes = ..., get_channel_request: builtins.int = ..., get_channel_response: meshtastic.protobuf.channel_pb2.Channel | None = ..., get_owner_request: builtins.bool = ..., @@ -496,18 +527,20 @@ class AdminMessage(google.protobuf.message.Message): remove_favorite_node: builtins.int = ..., set_fixed_position: meshtastic.protobuf.mesh_pb2.Position | None = ..., remove_fixed_position: builtins.bool = ..., + set_time_only: builtins.int = ..., begin_edit_settings: builtins.bool = ..., commit_edit_settings: builtins.bool = ..., + factory_reset_device: builtins.int = ..., reboot_ota_seconds: builtins.int = ..., exit_simulator: builtins.bool = ..., reboot_seconds: builtins.int = ..., shutdown_seconds: builtins.int = ..., - factory_reset: builtins.int = ..., + factory_reset_config: builtins.int = ..., nodedb_reset: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> 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", "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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... + def HasField(self, field_name: typing.Literal["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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_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"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_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"]) -> 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", "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", "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 diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index 95492a4..ef92476 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xdc#\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x1a\xa7\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eserial_enabled\x18\x02 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x12\n\nis_managed\x18\t \x01(\x08\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xdb\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\x94\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x12\n\x0eVERY_LONG_SLOW\x10\x02\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x1a\xd6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\x1e\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x42\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xf5&\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x1a\xb3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x1d\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xf0\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\xa9\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x1a\xda\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\"\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xd9\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x01(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12!\n\x19\x62luetooth_logging_enabled\x18\x07 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,52 +23,66 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014ConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._options = None _CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._serialized_options = b'\010\001' + _CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._options = None + _CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._serialized_options = b'\030\001' + _CONFIG_DEVICECONFIG.fields_by_name['debug_log_enabled']._options = None + _CONFIG_DEVICECONFIG.fields_by_name['debug_log_enabled']._serialized_options = b'\030\001' + _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._options = None + _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._serialized_options = b'\030\001' _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._serialized_options = b'\030\001' _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' + _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._options = None + _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001' + _CONFIG_BLUETOOTHCONFIG.fields_by_name['device_logging_enabled']._options = None + _CONFIG_BLUETOOTHCONFIG.fields_by_name['device_logging_enabled']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=4630 - _globals['_CONFIG_DEVICECONFIG']._serialized_start=497 - _globals['_CONFIG_DEVICECONFIG']._serialized_end=1176 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=919 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1093 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1095 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1176 - _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1179 - _globals['_CONFIG_POSITIONCONFIG']._serialized_end=1845 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=1619 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=1790 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1792 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1845 - _globals['_CONFIG_POWERCONFIG']._serialized_start=1848 - _globals['_CONFIG_POWERCONFIG']._serialized_end=2108 - _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2111 - _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2511 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2404 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2474 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2476 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2511 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2514 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3532 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3078 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3155 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3157 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3197 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3199 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3276 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3278 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3343 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3346 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3532 - _globals['_CONFIG_LORACONFIG']._serialized_start=3535 - _globals['_CONFIG_LORACONFIG']._serialized_end=4394 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4038 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4243 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4246 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4394 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4397 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4611 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4555 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4611 + _globals['_CONFIG']._serialized_end=5039 + _globals['_CONFIG_DEVICECONFIG']._serialized_start=629 + _globals['_CONFIG_DEVICECONFIG']._serialized_end=1320 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1063 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1237 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1239 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1320 + _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1323 + _globals['_CONFIG_POSITIONCONFIG']._serialized_end=1989 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=1763 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=1934 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1936 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1989 + _globals['_CONFIG_POWERCONFIG']._serialized_start=1992 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2252 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2255 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2655 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2548 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2618 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2620 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2655 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2658 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3676 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3222 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3299 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3301 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3341 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3343 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3420 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3422 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3487 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3490 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3676 + _globals['_CONFIG_LORACONFIG']._serialized_start=3679 + _globals['_CONFIG_LORACONFIG']._serialized_end=4559 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4182 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4387 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4390 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4559 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4562 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4780 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4724 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4780 + _globals['_CONFIG_SECURITYCONFIG']._serialized_start=4783 + _globals['_CONFIG_SECURITYCONFIG']._serialized_end=5000 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=5002 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=5020 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index d966d2c..0b32e91 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -256,11 +256,13 @@ class Config(google.protobuf.message.Message): serial_enabled: builtins.bool """ Disabling this will disable the SerialConsole by not initilizing the StreamAPI + Moved to SecurityConfig """ debug_log_enabled: builtins.bool """ By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). Set this to true to leave the debug log outputting even when API is active. + Moved to SecurityConfig """ button_gpio: builtins.int """ @@ -289,6 +291,7 @@ class Config(google.protobuf.message.Message): """ If true, device is considered to be "managed" by a mesh administrator Clients should then limit available configuration and administrative options inside the user interface + Moved to SecurityConfig """ disable_triple_click: builtins.bool """ @@ -1303,6 +1306,7 @@ class Config(google.protobuf.message.Message): VERY_LONG_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 2 """ Very Long Range - Slow + Deprecated in 2.5: Works only with txco and is unusably slow """ MEDIUM_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 3 """ @@ -1324,6 +1328,12 @@ class Config(google.protobuf.message.Message): """ Long Range - Moderately Fast """ + SHORT_TURBO: Config.LoRaConfig._ModemPreset.ValueType # 8 + """ + Short Range - Turbo + This is the fastest preset and the only one with 500kHz bandwidth. + It is not legal to use in all regions due to this wider bandwidth. + """ class ModemPreset(_ModemPreset, metaclass=_ModemPresetEnumTypeWrapper): """ @@ -1342,6 +1352,7 @@ class Config(google.protobuf.message.Message): VERY_LONG_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 2 """ Very Long Range - Slow + Deprecated in 2.5: Works only with txco and is unusably slow """ MEDIUM_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 3 """ @@ -1363,6 +1374,12 @@ class Config(google.protobuf.message.Message): """ Long Range - Moderately Fast """ + SHORT_TURBO: Config.LoRaConfig.ModemPreset.ValueType # 8 + """ + Short Range - Turbo + This is the fastest preset and the only one with 500kHz bandwidth. + It is not legal to use in all regions due to this wider bandwidth. + """ USE_PRESET_FIELD_NUMBER: builtins.int MODEM_PRESET_FIELD_NUMBER: builtins.int @@ -1561,6 +1578,7 @@ class Config(google.protobuf.message.Message): device_logging_enabled: builtins.bool """ Enables device (serial style logs) over Bluetooth + Moved to SecurityConfig """ def __init__( self, @@ -1572,6 +1590,80 @@ class Config(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing.Literal["device_logging_enabled", b"device_logging_enabled", "enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... + @typing.final + class SecurityConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PUBLIC_KEY_FIELD_NUMBER: builtins.int + PRIVATE_KEY_FIELD_NUMBER: builtins.int + ADMIN_KEY_FIELD_NUMBER: builtins.int + IS_MANAGED_FIELD_NUMBER: builtins.int + SERIAL_ENABLED_FIELD_NUMBER: builtins.int + DEBUG_LOG_API_ENABLED_FIELD_NUMBER: builtins.int + BLUETOOTH_LOGGING_ENABLED_FIELD_NUMBER: builtins.int + ADMIN_CHANNEL_ENABLED_FIELD_NUMBER: builtins.int + public_key: builtins.bytes + """ + The public key of the user's device. + Sent out to other nodes on the mesh to allow them to compute a shared secret key. + """ + private_key: builtins.bytes + """ + The private key of the device. + Used to create a shared key with a remote device. + """ + admin_key: builtins.bytes + """ + The public key authorized to send admin messages to this node. + """ + is_managed: builtins.bool + """ + If true, device is considered to be "managed" by a mesh administrator via admin messages + Device is managed by a mesh administrator. + """ + serial_enabled: builtins.bool + """ + Serial Console over the Stream API." + """ + debug_log_api_enabled: builtins.bool + """ + By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). + Output live debug logging over serial. + """ + bluetooth_logging_enabled: builtins.bool + """ + Enables device (serial style logs) over Bluetooth + """ + admin_channel_enabled: builtins.bool + """ + Allow incoming device control over the insecure legacy admin channel. + """ + def __init__( + self, + *, + public_key: builtins.bytes = ..., + private_key: builtins.bytes = ..., + admin_key: builtins.bytes = ..., + is_managed: builtins.bool = ..., + serial_enabled: builtins.bool = ..., + debug_log_api_enabled: builtins.bool = ..., + bluetooth_logging_enabled: builtins.bool = ..., + admin_channel_enabled: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["admin_channel_enabled", b"admin_channel_enabled", "admin_key", b"admin_key", "bluetooth_logging_enabled", b"bluetooth_logging_enabled", "debug_log_api_enabled", b"debug_log_api_enabled", "is_managed", b"is_managed", "private_key", b"private_key", "public_key", b"public_key", "serial_enabled", b"serial_enabled"]) -> None: ... + + @typing.final + class SessionkeyConfig(google.protobuf.message.Message): + """ + Blank config request, strictly for getting the session key + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + DEVICE_FIELD_NUMBER: builtins.int POSITION_FIELD_NUMBER: builtins.int POWER_FIELD_NUMBER: builtins.int @@ -1579,6 +1671,8 @@ class Config(google.protobuf.message.Message): DISPLAY_FIELD_NUMBER: builtins.int LORA_FIELD_NUMBER: builtins.int BLUETOOTH_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int + SESSIONKEY_FIELD_NUMBER: builtins.int @property def device(self) -> global___Config.DeviceConfig: ... @property @@ -1593,6 +1687,10 @@ class Config(google.protobuf.message.Message): def lora(self) -> global___Config.LoRaConfig: ... @property def bluetooth(self) -> global___Config.BluetoothConfig: ... + @property + def security(self) -> global___Config.SecurityConfig: ... + @property + def sessionkey(self) -> global___Config.SessionkeyConfig: ... def __init__( self, *, @@ -1603,9 +1701,11 @@ class Config(google.protobuf.message.Message): display: global___Config.DisplayConfig | None = ..., lora: global___Config.LoRaConfig | None = ..., bluetooth: global___Config.BluetoothConfig | None = ..., + security: global___Config.SecurityConfig | None = ..., + sessionkey: global___Config.SessionkeyConfig | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["device", "position", "power", "network", "display", "lora", "bluetooth"] | None: ... + def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power", "security", b"security", "sessionkey", b"sessionkey"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "payload_variant", b"payload_variant", "position", b"position", "power", b"power", "security", b"security", "sessionkey", b"sessionkey"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["device", "position", "power", "network", "display", "lora", "bluetooth", "security", "sessionkey"] | None: ... global___Config = Config diff --git a/meshtastic/protobuf/deviceonly_pb2.py b/meshtastic/protobuf/deviceonly_pb2.py index 1a3210c..31f1c68 100644 --- a/meshtastic/protobuf/deviceonly_pb2.py +++ b/meshtastic/protobuf/deviceonly_pb2.py @@ -15,10 +15,11 @@ from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_chann 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 config_pb2 as meshtastic_dot_protobuf_dot_config__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/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.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\"\xa1\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\x82\x04\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\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\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\x12\x63\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"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\"\xb2\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x32\n\x08oem_font\x18\x04 \x01(\x0e\x32 .meshtastic.protobuf.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12:\n\x10oem_local_config\x18\x07 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12G\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/config.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\"\xa5\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\x82\x04\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\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\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\x12\x63\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"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\"\xb2\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x32\n\x08oem_font\x18\x04 \x01(\x0e\x32 .meshtastic.protobuf.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12:\n\x10oem_local_config\x18\x07 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12G\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,20 +27,24 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceo if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010' + _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 _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' _DEVICESTATE.fields_by_name['node_db_lite']._options = None _DEVICESTATE.fields_by_name['node_db_lite']._serialized_options = b'\222?\'\222\001$std::vector' - _globals['_SCREENFONTS']._serialized_start=1570 - _globals['_SCREENFONTS']._serialized_end=1632 - _globals['_POSITIONLITE']._serialized_start=217 - _globals['_POSITIONLITE']._serialized_end=370 - _globals['_NODEINFOLITE']._serialized_start=373 - _globals['_NODEINFOLITE']._serialized_end=662 - _globals['_DEVICESTATE']._serialized_start=665 - _globals['_DEVICESTATE']._serialized_end=1179 - _globals['_CHANNELFILE']._serialized_start=1181 - _globals['_CHANNELFILE']._serialized_end=1259 - _globals['_OEMSTORE']._serialized_start=1262 - _globals['_OEMSTORE']._serialized_end=1568 + _globals['_SCREENFONTS']._serialized_start=1837 + _globals['_SCREENFONTS']._serialized_end=1899 + _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=929 + _globals['_DEVICESTATE']._serialized_start=932 + _globals['_DEVICESTATE']._serialized_end=1446 + _globals['_CHANNELFILE']._serialized_start=1448 + _globals['_CHANNELFILE']._serialized_end=1526 + _globals['_OEMSTORE']._serialized_start=1529 + _globals['_OEMSTORE']._serialized_end=1835 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/deviceonly_pb2.pyi b/meshtastic/protobuf/deviceonly_pb2.pyi index c0ca537..747b304 100644 --- a/meshtastic/protobuf/deviceonly_pb2.pyi +++ b/meshtastic/protobuf/deviceonly_pb2.pyi @@ -10,6 +10,7 @@ import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import meshtastic.protobuf.channel_pb2 +import meshtastic.protobuf.config_pb2 import meshtastic.protobuf.localonly_pb2 import meshtastic.protobuf.mesh_pb2 import meshtastic.protobuf.telemetry_pb2 @@ -112,6 +113,67 @@ class PositionLite(google.protobuf.message.Message): global___PositionLite = PositionLite +@typing.final +class UserLite(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MACADDR_FIELD_NUMBER: builtins.int + LONG_NAME_FIELD_NUMBER: builtins.int + SHORT_NAME_FIELD_NUMBER: builtins.int + HW_MODEL_FIELD_NUMBER: builtins.int + IS_LICENSED_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + PUBLIC_KEY_FIELD_NUMBER: builtins.int + macaddr: builtins.bytes + """ + This is the addr of the radio. + """ + long_name: builtins.str + """ + A full name for this user, i.e. "Kevin Hester" + """ + short_name: builtins.str + """ + A VERY short name, ideally two characters. + Suitable for a tiny OLED screen + """ + hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType + """ + TBEAM, HELTEC, etc... + Starting in 1.2.11 moved to hw_model enum in the NodeInfo object. + Apps will still need the string here for older builds + (so OTA update can find the right image), but if the enum is available it will be used instead. + """ + is_licensed: builtins.bool + """ + In some regions Ham radio operators have different bandwidth limitations than others. + If this user is a licensed operator, set this flag. + Also, "long_name" should be their licence number. + """ + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType + """ + Indicates that the user's role in the mesh + """ + public_key: builtins.bytes + """ + 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. + """ + def __init__( + self, + *, + macaddr: builtins.bytes = ..., + long_name: builtins.str = ..., + short_name: builtins.str = ..., + hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType = ..., + is_licensed: builtins.bool = ..., + role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ..., + public_key: builtins.bytes = ..., + ) -> 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 + @typing.final class NodeInfoLite(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -157,7 +219,7 @@ class NodeInfoLite(google.protobuf.message.Message): Persists between NodeDB internal clean ups """ @property - def user(self) -> meshtastic.protobuf.mesh_pb2.User: + def user(self) -> global___UserLite: """ The user info for this node """ @@ -179,7 +241,7 @@ class NodeInfoLite(google.protobuf.message.Message): self, *, num: builtins.int = ..., - user: meshtastic.protobuf.mesh_pb2.User | None = ..., + user: global___UserLite | None = ..., position: global___PositionLite | None = ..., snr: builtins.float = ..., last_heard: builtins.int = ..., diff --git a/meshtastic/protobuf/localonly_pb2.py b/meshtastic/protobuf/localonly_pb2.py index f4e4d71..96164fa 100644 --- a/meshtastic/protobuf/localonly_pb2.py +++ b/meshtastic/protobuf/localonly_pb2.py @@ -15,7 +15,7 @@ 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\"\xbc\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\"\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') +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) @@ -24,7 +24,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None 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=580 - _globals['_LOCALMODULECONFIG']._serialized_start=583 - _globals['_LOCALMODULECONFIG']._serialized_end=1591 + _globals['_LOCALCONFIG']._serialized_end=642 + _globals['_LOCALMODULECONFIG']._serialized_start=645 + _globals['_LOCALMODULECONFIG']._serialized_end=1653 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/localonly_pb2.pyi b/meshtastic/protobuf/localonly_pb2.pyi index ca62f18..059ef1a 100644 --- a/meshtastic/protobuf/localonly_pb2.pyi +++ b/meshtastic/protobuf/localonly_pb2.pyi @@ -29,6 +29,7 @@ class LocalConfig(google.protobuf.message.Message): LORA_FIELD_NUMBER: builtins.int BLUETOOTH_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int version: builtins.int """ A version integer used to invalidate old save files when we make @@ -77,6 +78,12 @@ class LocalConfig(google.protobuf.message.Message): The part of the config that is specific to the Bluetooth settings """ + @property + def security(self) -> meshtastic.protobuf.config_pb2.Config.SecurityConfig: + """ + The part of the config that is specific to Security settings + """ + def __init__( self, *, @@ -88,9 +95,10 @@ class LocalConfig(google.protobuf.message.Message): lora: meshtastic.protobuf.config_pb2.Config.LoRaConfig | None = ..., bluetooth: meshtastic.protobuf.config_pb2.Config.BluetoothConfig | None = ..., version: builtins.int = ..., + security: meshtastic.protobuf.config_pb2.Config.SecurityConfig | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "version", b"version"]) -> None: ... + def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "security", b"security"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "security", b"security", "version", b"version"]) -> None: ... global___LocalConfig = LocalConfig diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 6016cdd..425fbfa 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xd0\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xbf\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xf2\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xdb\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x9a\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,70 +31,72 @@ if _descriptor._USE_C_DESCRIPTORS == False: _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _globals['_HARDWAREMODEL']._serialized_start=5544 - _globals['_HARDWAREMODEL']._serialized_end=6904 - _globals['_CONSTANTS']._serialized_start=6906 - _globals['_CONSTANTS']._serialized_end=6950 - _globals['_CRITICALERRORCODE']._serialized_start=6953 - _globals['_CRITICALERRORCODE']._serialized_end=7191 + _globals['_HARDWAREMODEL']._serialized_start=6123 + _globals['_HARDWAREMODEL']._serialized_end=7557 + _globals['_CONSTANTS']._serialized_start=7559 + _globals['_CONSTANTS']._serialized_end=7603 + _globals['_CRITICALERRORCODE']._serialized_start=7606 + _globals['_CRITICALERRORCODE']._serialized_end=7914 _globals['_POSITION']._serialized_start=273 - _globals['_POSITION']._serialized_end=1032 - _globals['_POSITION_LOCSOURCE']._serialized_start=854 - _globals['_POSITION_LOCSOURCE']._serialized_end=932 - _globals['_POSITION_ALTSOURCE']._serialized_start=934 - _globals['_POSITION_ALTSOURCE']._serialized_end=1032 - _globals['_USER']._serialized_start=1035 - _globals['_USER']._serialized_end=1249 - _globals['_ROUTEDISCOVERY']._serialized_start=1251 - _globals['_ROUTEDISCOVERY']._serialized_end=1282 - _globals['_ROUTING']._serialized_start=1285 - _globals['_ROUTING']._serialized_end=1692 - _globals['_ROUTING_ERROR']._serialized_start=1479 - _globals['_ROUTING_ERROR']._serialized_end=1681 - _globals['_DATA']._serialized_start=1695 - _globals['_DATA']._serialized_end=1871 - _globals['_WAYPOINT']._serialized_start=1874 - _globals['_WAYPOINT']._serialized_end=2021 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2023 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2131 - _globals['_MESHPACKET']._serialized_start=2134 - _globals['_MESHPACKET']._serialized_end=2694 - _globals['_MESHPACKET_PRIORITY']._serialized_start=2516 - _globals['_MESHPACKET_PRIORITY']._serialized_end=2607 - _globals['_MESHPACKET_DELAYED']._serialized_start=2609 - _globals['_MESHPACKET_DELAYED']._serialized_end=2675 - _globals['_NODEINFO']._serialized_start=2697 - _globals['_NODEINFO']._serialized_end=2978 - _globals['_MYNODEINFO']._serialized_start=2980 - _globals['_MYNODEINFO']._serialized_end=3060 - _globals['_LOGRECORD']._serialized_start=3063 - _globals['_LOGRECORD']._serialized_end=3264 - _globals['_LOGRECORD_LEVEL']._serialized_start=3176 - _globals['_LOGRECORD_LEVEL']._serialized_end=3264 - _globals['_QUEUESTATUS']._serialized_start=3266 - _globals['_QUEUESTATUS']._serialized_end=3346 - _globals['_FROMRADIO']._serialized_start=3349 - _globals['_FROMRADIO']._serialized_end=4102 - _globals['_FILEINFO']._serialized_start=4104 - _globals['_FILEINFO']._serialized_end=4153 - _globals['_TORADIO']._serialized_start=4156 - _globals['_TORADIO']._serialized_end=4468 - _globals['_COMPRESSED']._serialized_start=4470 - _globals['_COMPRESSED']._serialized_end=4543 - _globals['_NEIGHBORINFO']._serialized_start=4546 - _globals['_NEIGHBORINFO']._serialized_end=4690 - _globals['_NEIGHBOR']._serialized_start=4692 - _globals['_NEIGHBOR']._serialized_end=4792 - _globals['_DEVICEMETADATA']._serialized_start=4795 - _globals['_DEVICEMETADATA']._serialized_end=5114 - _globals['_HEARTBEAT']._serialized_start=5116 - _globals['_HEARTBEAT']._serialized_end=5127 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5129 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5223 - _globals['_CHUNKEDPAYLOAD']._serialized_start=5225 - _globals['_CHUNKEDPAYLOAD']._serialized_end=5326 - _globals['_RESEND_CHUNKS']._serialized_start=5328 - _globals['_RESEND_CHUNKS']._serialized_end=5359 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5362 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=5541 + _globals['_POSITION']._serialized_end=1194 + _globals['_POSITION_LOCSOURCE']._serialized_start=889 + _globals['_POSITION_LOCSOURCE']._serialized_end=967 + _globals['_POSITION_ALTSOURCE']._serialized_start=969 + _globals['_POSITION_ALTSOURCE']._serialized_end=1067 + _globals['_USER']._serialized_start=1197 + _globals['_USER']._serialized_end=1431 + _globals['_ROUTEDISCOVERY']._serialized_start=1433 + _globals['_ROUTEDISCOVERY']._serialized_end=1523 + _globals['_ROUTING']._serialized_start=1526 + _globals['_ROUTING']._serialized_end=1973 + _globals['_ROUTING_ERROR']._serialized_start=1720 + _globals['_ROUTING_ERROR']._serialized_end=1962 + _globals['_DATA']._serialized_start=1976 + _globals['_DATA']._serialized_end=2152 + _globals['_WAYPOINT']._serialized_start=2155 + _globals['_WAYPOINT']._serialized_end=2343 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2345 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2453 + _globals['_MESHPACKET']._serialized_start=2456 + _globals['_MESHPACKET']._serialized_end=3059 + _globals['_MESHPACKET_PRIORITY']._serialized_start=2881 + _globals['_MESHPACKET_PRIORITY']._serialized_end=2972 + _globals['_MESHPACKET_DELAYED']._serialized_start=2974 + _globals['_MESHPACKET_DELAYED']._serialized_end=3040 + _globals['_NODEINFO']._serialized_start=3062 + _globals['_NODEINFO']._serialized_end=3343 + _globals['_MYNODEINFO']._serialized_start=3345 + _globals['_MYNODEINFO']._serialized_end=3425 + _globals['_LOGRECORD']._serialized_start=3428 + _globals['_LOGRECORD']._serialized_end=3629 + _globals['_LOGRECORD_LEVEL']._serialized_start=3541 + _globals['_LOGRECORD_LEVEL']._serialized_end=3629 + _globals['_QUEUESTATUS']._serialized_start=3631 + _globals['_QUEUESTATUS']._serialized_end=3711 + _globals['_FROMRADIO']._serialized_start=3714 + _globals['_FROMRADIO']._serialized_end=4538 + _globals['_CLIENTNOTIFICATION']._serialized_start=4541 + _globals['_CLIENTNOTIFICATION']._serialized_end=4681 + _globals['_FILEINFO']._serialized_start=4683 + _globals['_FILEINFO']._serialized_end=4732 + _globals['_TORADIO']._serialized_start=4735 + _globals['_TORADIO']._serialized_end=5047 + _globals['_COMPRESSED']._serialized_start=5049 + _globals['_COMPRESSED']._serialized_end=5122 + _globals['_NEIGHBORINFO']._serialized_start=5125 + _globals['_NEIGHBORINFO']._serialized_end=5269 + _globals['_NEIGHBOR']._serialized_start=5271 + _globals['_NEIGHBOR']._serialized_end=5371 + _globals['_DEVICEMETADATA']._serialized_start=5374 + _globals['_DEVICEMETADATA']._serialized_end=5693 + _globals['_HEARTBEAT']._serialized_start=5695 + _globals['_HEARTBEAT']._serialized_end=5706 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5708 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5802 + _globals['_CHUNKEDPAYLOAD']._serialized_start=5804 + _globals['_CHUNKEDPAYLOAD']._serialized_end=5905 + _globals['_RESEND_CHUNKS']._serialized_start=5907 + _globals['_RESEND_CHUNKS']._serialized_end=5938 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5941 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=6120 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 2e53c48..570fe2e 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -332,6 +332,23 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. """ + RAK3172: _HardwareModel.ValueType # 72 + """ + RAK3172 STM32WLE5 Module (https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172) + """ + WIO_E5: _HardwareModel.ValueType # 73 + """ + Seeed Studio Wio-E5 (either mini or Dev kit) using STM32WL chip. + """ + RADIOMASTER_900_BANDIT: _HardwareModel.ValueType # 74 + """ + RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module + SSD1306 OLED and No GPS + """ + ME25LS01_4Y10TD: _HardwareModel.ValueType # 75 + """ + Minewsemi ME25LS01 (ME25LE01_V1.0). NRF52840 w/ LR1110 radio, buttons and leds and pins. + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -648,6 +665,23 @@ TRACKER_T1000_E: HardwareModel.ValueType # 71 """ Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. """ +RAK3172: HardwareModel.ValueType # 72 +""" +RAK3172 STM32WLE5 Module (https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172) +""" +WIO_E5: HardwareModel.ValueType # 73 +""" +Seeed Studio Wio-E5 (either mini or Dev kit) using STM32WL chip. +""" +RADIOMASTER_900_BANDIT: HardwareModel.ValueType # 74 +""" +RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module +SSD1306 OLED and No GPS +""" +ME25LS01_4Y10TD: HardwareModel.ValueType # 75 +""" +Minewsemi ME25LS01 (ME25LE01_V1.0). NRF52840 w/ LR1110 radio, buttons and leds and pins. +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -747,6 +781,17 @@ class _CriticalErrorCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapp A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug """ + FLASH_CORRUPTION_RECOVERABLE: _CriticalErrorCode.ValueType # 12 + """ + Corruption was detected on the flash filesystem but we were able to repair things. + If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. + """ + FLASH_CORRUPTION_UNRECOVERABLE: _CriticalErrorCode.ValueType # 13 + """ + Corruption was detected on the flash filesystem but we were unable to repair things. + NOTE: Your node will probably need to be reconfigured the next time it reboots (it will lose the region code etc...) + If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. + """ class CriticalErrorCode(_CriticalErrorCode, metaclass=_CriticalErrorCodeEnumTypeWrapper): """ @@ -805,6 +850,17 @@ RADIO_SPI_BUG: CriticalErrorCode.ValueType # 11 A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug """ +FLASH_CORRUPTION_RECOVERABLE: CriticalErrorCode.ValueType # 12 +""" +Corruption was detected on the flash filesystem but we were able to repair things. +If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. +""" +FLASH_CORRUPTION_UNRECOVERABLE: CriticalErrorCode.ValueType # 13 +""" +Corruption was detected on the flash filesystem but we were unable to repair things. +NOTE: Your node will probably need to be reconfigured the next time it reboots (it will lose the region code etc...) +If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. +""" global___CriticalErrorCode = CriticalErrorCode @typing.final @@ -1051,22 +1107,22 @@ class Position(google.protobuf.message.Message): def __init__( self, *, - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., - altitude: builtins.int = ..., + latitude_i: builtins.int | None = ..., + longitude_i: builtins.int | None = ..., + altitude: builtins.int | None = ..., time: builtins.int = ..., location_source: global___Position.LocSource.ValueType = ..., altitude_source: global___Position.AltSource.ValueType = ..., timestamp: builtins.int = ..., timestamp_millis_adjust: builtins.int = ..., - altitude_hae: builtins.int = ..., - altitude_geoidal_separation: builtins.int = ..., + altitude_hae: builtins.int | None = ..., + altitude_geoidal_separation: builtins.int | None = ..., PDOP: builtins.int = ..., HDOP: builtins.int = ..., VDOP: builtins.int = ..., gps_accuracy: builtins.int = ..., - ground_speed: builtins.int = ..., - ground_track: builtins.int = ..., + ground_speed: builtins.int | None = ..., + ground_track: builtins.int | None = ..., fix_quality: builtins.int = ..., fix_type: builtins.int = ..., sats_in_view: builtins.int = ..., @@ -1075,7 +1131,22 @@ class Position(google.protobuf.message.Message): seq_number: builtins.int = ..., precision_bits: builtins.int = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["HDOP", b"HDOP", "PDOP", b"PDOP", "VDOP", b"VDOP", "altitude", b"altitude", "altitude_geoidal_separation", b"altitude_geoidal_separation", "altitude_hae", b"altitude_hae", "altitude_source", b"altitude_source", "fix_quality", b"fix_quality", "fix_type", b"fix_type", "gps_accuracy", b"gps_accuracy", "ground_speed", b"ground_speed", "ground_track", b"ground_track", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "next_update", b"next_update", "precision_bits", b"precision_bits", "sats_in_view", b"sats_in_view", "sensor_id", b"sensor_id", "seq_number", b"seq_number", "time", b"time", "timestamp", b"timestamp", "timestamp_millis_adjust", b"timestamp_millis_adjust"]) -> None: ... + def HasField(self, field_name: typing.Literal["_altitude", b"_altitude", "_altitude_geoidal_separation", b"_altitude_geoidal_separation", "_altitude_hae", b"_altitude_hae", "_ground_speed", b"_ground_speed", "_ground_track", b"_ground_track", "_latitude_i", b"_latitude_i", "_longitude_i", b"_longitude_i", "altitude", b"altitude", "altitude_geoidal_separation", b"altitude_geoidal_separation", "altitude_hae", b"altitude_hae", "ground_speed", b"ground_speed", "ground_track", b"ground_track", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["HDOP", b"HDOP", "PDOP", b"PDOP", "VDOP", b"VDOP", "_altitude", b"_altitude", "_altitude_geoidal_separation", b"_altitude_geoidal_separation", "_altitude_hae", b"_altitude_hae", "_ground_speed", b"_ground_speed", "_ground_track", b"_ground_track", "_latitude_i", b"_latitude_i", "_longitude_i", b"_longitude_i", "altitude", b"altitude", "altitude_geoidal_separation", b"altitude_geoidal_separation", "altitude_hae", b"altitude_hae", "altitude_source", b"altitude_source", "fix_quality", b"fix_quality", "fix_type", b"fix_type", "gps_accuracy", b"gps_accuracy", "ground_speed", b"ground_speed", "ground_track", b"ground_track", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "next_update", b"next_update", "precision_bits", b"precision_bits", "sats_in_view", b"sats_in_view", "sensor_id", b"sensor_id", "seq_number", b"seq_number", "time", b"time", "timestamp", b"timestamp", "timestamp_millis_adjust", b"timestamp_millis_adjust"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_altitude", b"_altitude"]) -> typing.Literal["altitude"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_altitude_geoidal_separation", b"_altitude_geoidal_separation"]) -> typing.Literal["altitude_geoidal_separation"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_altitude_hae", b"_altitude_hae"]) -> typing.Literal["altitude_hae"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ground_speed", b"_ground_speed"]) -> typing.Literal["ground_speed"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ground_track", b"_ground_track"]) -> typing.Literal["ground_track"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_latitude_i", b"_latitude_i"]) -> typing.Literal["latitude_i"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_longitude_i", b"_longitude_i"]) -> typing.Literal["longitude_i"] | None: ... global___Position = Position @@ -1113,6 +1184,7 @@ class User(google.protobuf.message.Message): HW_MODEL_FIELD_NUMBER: builtins.int IS_LICENSED_FIELD_NUMBER: builtins.int ROLE_FIELD_NUMBER: builtins.int + PUBLIC_KEY_FIELD_NUMBER: builtins.int id: builtins.str """ A globally unique ID string for this user. @@ -1152,6 +1224,11 @@ class User(google.protobuf.message.Message): """ Indicates that the user's role in the mesh """ + public_key: builtins.bytes + """ + 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. + """ def __init__( self, *, @@ -1162,32 +1239,57 @@ class User(google.protobuf.message.Message): hw_model: global___HardwareModel.ValueType = ..., is_licensed: builtins.bool = ..., role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ..., + public_key: builtins.bytes = ..., ) -> 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", "role", b"role", "short_name", b"short_name"]) -> 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 @typing.final class RouteDiscovery(google.protobuf.message.Message): """ - A message used in our Dynamic Source Routing protocol (RFC 4728 based) + A message used in a traceroute """ DESCRIPTOR: google.protobuf.descriptor.Descriptor ROUTE_FIELD_NUMBER: builtins.int + SNR_TOWARDS_FIELD_NUMBER: builtins.int + ROUTE_BACK_FIELD_NUMBER: builtins.int + SNR_BACK_FIELD_NUMBER: builtins.int @property def route(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: """ - The list of nodenums this packet has visited so far + The list of nodenums this packet has visited so far to the destination. + """ + + @property + def snr_towards(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """ + The list of SNRs (in dB, scaled by 4) in the route towards the destination. + """ + + @property + def route_back(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """ + The list of nodenums the packet has visited on the way back from the destination. + """ + + @property + def snr_back(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """ + The list of SNRs (in dB, scaled by 4) in the route back from the destination. """ def __init__( self, *, route: collections.abc.Iterable[builtins.int] | None = ..., + snr_towards: collections.abc.Iterable[builtins.int] | None = ..., + route_back: collections.abc.Iterable[builtins.int] | None = ..., + snr_back: collections.abc.Iterable[builtins.int] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["route", b"route"]) -> None: ... + def ClearField(self, field_name: typing.Literal["route", b"route", "route_back", b"route_back", "snr_back", b"snr_back", "snr_towards", b"snr_towards"]) -> None: ... global___RouteDiscovery = RouteDiscovery @@ -1255,6 +1357,14 @@ class Routing(google.protobuf.message.Message): The application layer service on the remote node received your request, but considered your request not authorized (i.e you did not send the request on the required bound channel) """ + PKI_FAILED: Routing._Error.ValueType # 34 + """ + The client specified a PKI transport, but the node was unable to send the packet using PKI (and did not send the message at all) + """ + PKI_UNKNOWN_PUBKEY: Routing._Error.ValueType # 35 + """ + The receiving node does not have a Public Key to decode with + """ class Error(_Error, metaclass=_ErrorEnumTypeWrapper): """ @@ -1312,6 +1422,14 @@ class Routing(google.protobuf.message.Message): The application layer service on the remote node received your request, but considered your request not authorized (i.e you did not send the request on the required bound channel) """ + PKI_FAILED: Routing.Error.ValueType # 34 + """ + The client specified a PKI transport, but the node was unable to send the packet using PKI (and did not send the message at all) + """ + PKI_UNKNOWN_PUBKEY: Routing.Error.ValueType # 35 + """ + The receiving node does not have a Public Key to decode with + """ ROUTE_REQUEST_FIELD_NUMBER: builtins.int ROUTE_REPLY_FIELD_NUMBER: builtins.int @@ -1475,15 +1593,20 @@ class Waypoint(google.protobuf.message.Message): self, *, id: builtins.int = ..., - latitude_i: builtins.int = ..., - longitude_i: builtins.int = ..., + latitude_i: builtins.int | None = ..., + longitude_i: builtins.int | None = ..., expire: builtins.int = ..., locked_to: builtins.int = ..., name: builtins.str = ..., description: builtins.str = ..., icon: builtins.int = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["description", b"description", "expire", b"expire", "icon", b"icon", "id", b"id", "latitude_i", b"latitude_i", "locked_to", b"locked_to", "longitude_i", b"longitude_i", "name", b"name"]) -> None: ... + def HasField(self, field_name: typing.Literal["_latitude_i", b"_latitude_i", "_longitude_i", b"_longitude_i", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_latitude_i", b"_latitude_i", "_longitude_i", b"_longitude_i", "description", b"description", "expire", b"expire", "icon", b"icon", "id", b"id", "latitude_i", b"latitude_i", "locked_to", b"locked_to", "longitude_i", b"longitude_i", "name", b"name"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_latitude_i", b"_latitude_i"]) -> typing.Literal["latitude_i"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_longitude_i", b"_longitude_i"]) -> typing.Literal["longitude_i"] | None: ... global___Waypoint = Waypoint @@ -1683,6 +1806,8 @@ class MeshPacket(google.protobuf.message.Message): DELAYED_FIELD_NUMBER: builtins.int VIA_MQTT_FIELD_NUMBER: builtins.int HOP_START_FIELD_NUMBER: builtins.int + PUBLIC_KEY_FIELD_NUMBER: builtins.int + PKI_ENCRYPTED_FIELD_NUMBER: builtins.int to: builtins.int """ The (immediate) destination for this packet @@ -1766,6 +1891,14 @@ class MeshPacket(google.protobuf.message.Message): Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header. When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled. """ + public_key: builtins.bytes + """ + Records the public key the packet was encrypted with, if applicable. + """ + pki_encrypted: builtins.bool + """ + Indicates whether the packet was en/decrypted using PKI + """ @property def decoded(self) -> global___Data: """ @@ -1789,9 +1922,11 @@ class MeshPacket(google.protobuf.message.Message): delayed: global___MeshPacket.Delayed.ValueType = ..., via_mqtt: builtins.bool = ..., hop_start: builtins.int = ..., + public_key: builtins.bytes = ..., + pki_encrypted: builtins.bool = ..., ) -> 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", "payload_variant", b"payload_variant", "priority", b"priority", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "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", "payload_variant", b"payload_variant", "pki_encrypted", b"pki_encrypted", "priority", b"priority", "public_key", b"public_key", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "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 @@ -2109,6 +2244,7 @@ class FromRadio(google.protobuf.message.Message): METADATA_FIELD_NUMBER: builtins.int MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER: builtins.int FILEINFO_FIELD_NUMBER: builtins.int + CLIENTNOTIFICATION_FIELD_NUMBER: builtins.int id: builtins.int """ The packet id, used to allow the phone to request missing read packets from the FIFO, @@ -2202,6 +2338,12 @@ class FromRadio(google.protobuf.message.Message): File system manifest messages """ + @property + def clientNotification(self) -> global___ClientNotification: + """ + Notification message to the client + """ + def __init__( self, *, @@ -2220,13 +2362,59 @@ class FromRadio(google.protobuf.message.Message): metadata: global___DeviceMetadata | None = ..., mqttClientProxyMessage: global___MqttClientProxyMessage | None = ..., fileInfo: global___FileInfo | None = ..., + clientNotification: global___ClientNotification | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["channel", b"channel", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage", "fileInfo"] | None: ... + def HasField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "fileInfo", b"fileInfo", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage", "fileInfo", "clientNotification"] | None: ... global___FromRadio = FromRadio +@typing.final +class ClientNotification(google.protobuf.message.Message): + """ + A notification message from the device to the client + To be used for important messages that should to be displayed to the user + in the form of push notifications or validation messages when saving + invalid configuration. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REPLY_ID_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LEVEL_FIELD_NUMBER: builtins.int + MESSAGE_FIELD_NUMBER: builtins.int + reply_id: builtins.int + """ + The id of the packet we're notifying in response to + """ + time: builtins.int + """ + Seconds since 1970 - or 0 for unknown/unset + """ + level: global___LogRecord.Level.ValueType + """ + The level type of notification + """ + message: builtins.str + """ + The message body of the notification + """ + def __init__( + self, + *, + reply_id: builtins.int | None = ..., + time: builtins.int = ..., + level: global___LogRecord.Level.ValueType = ..., + message: builtins.str = ..., + ) -> None: ... + 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: ... + +global___ClientNotification = ClientNotification + @typing.final class FileInfo(google.protobuf.message.Message): """ diff --git a/meshtastic/protobuf/module_config_pb2.pyi b/meshtastic/protobuf/module_config_pb2.pyi index 5bc30ad..2615401 100644 --- a/meshtastic/protobuf/module_config_pb2.pyi +++ b/meshtastic/protobuf/module_config_pb2.pyi @@ -992,7 +992,7 @@ class ModuleConfig(google.protobuf.message.Message): allow_input_source: builtins.str """ Input event origin accepted by the canned message module. - Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any" + Can be e.g. "rotEnc1", "upDownEnc1", "scanAndSelect", "cardkb", "serialkb", or keyword "_any" """ send_bell: builtins.bool """ diff --git a/meshtastic/protobuf/portnums_pb2.pyi b/meshtastic/protobuf/portnums_pb2.pyi index 3c7546c..4f9a1d8 100644 --- a/meshtastic/protobuf/portnums_pb2.pyi +++ b/meshtastic/protobuf/portnums_pb2.pyi @@ -154,7 +154,7 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy TRACEROUTE_APP: _PortNum.ValueType # 70 """ Provides a traceroute functionality to show the route a packet towards - a certain destination would take on the mesh. + a certain destination would take on the mesh. Contains a RouteDiscovery message as payload. ENCODING: Protobuf """ NEIGHBORINFO_APP: _PortNum.ValueType # 71 @@ -339,7 +339,7 @@ ENCODING: Protobuf (?) TRACEROUTE_APP: PortNum.ValueType # 70 """ Provides a traceroute functionality to show the route a packet towards -a certain destination would take on the mesh. +a certain destination would take on the mesh. Contains a RouteDiscovery message as payload. ENCODING: Protobuf """ NEIGHBORINFO_APP: PortNum.ValueType # 71 diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 14b5351..3039500 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xdc\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\x12\x11\n\twind_gust\x18\x10 \x01(\x02\x12\x11\n\twind_lull\x18\x11 \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa4\x05\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lull\"\x8a\x02\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_current\"\xeb\x04\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100um\"\xd5\x01\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\"\xe5\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\x92\x03\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,18 +21,20 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemet if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=1377 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=1739 + _globals['_TELEMETRYSENSORTYPE']._serialized_start=2517 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=2919 _globals['_DEVICEMETRICS']._serialized_start=61 - _globals['_DEVICEMETRICS']._serialized_end=190 - _globals['_ENVIRONMENTMETRICS']._serialized_start=193 - _globals['_ENVIRONMENTMETRICS']._serialized_end=541 - _globals['_POWERMETRICS']._serialized_start=544 - _globals['_POWERMETRICS']._serialized_end=684 - _globals['_AIRQUALITYMETRICS']._serialized_start=687 - _globals['_AIRQUALITYMETRICS']._serialized_end=1006 - _globals['_TELEMETRY']._serialized_start=1009 - _globals['_TELEMETRY']._serialized_end=1310 - _globals['_NAU7802CONFIG']._serialized_start=1312 - _globals['_NAU7802CONFIG']._serialized_end=1374 + _globals['_DEVICEMETRICS']._serialized_end=304 + _globals['_ENVIRONMENTMETRICS']._serialized_start=307 + _globals['_ENVIRONMENTMETRICS']._serialized_end=983 + _globals['_POWERMETRICS']._serialized_start=986 + _globals['_POWERMETRICS']._serialized_end=1252 + _globals['_AIRQUALITYMETRICS']._serialized_start=1255 + _globals['_AIRQUALITYMETRICS']._serialized_end=1874 + _globals['_LOCALSTATS']._serialized_start=1877 + _globals['_LOCALSTATS']._serialized_end=2090 + _globals['_TELEMETRY']._serialized_start=2093 + _globals['_TELEMETRY']._serialized_end=2450 + _globals['_NAU7802CONFIG']._serialized_start=2452 + _globals['_NAU7802CONFIG']._serialized_end=2514 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index 83334ec..f528fcd 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -127,6 +127,18 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ NAU7802 Scale Chip or compatible """ + BMP3XX: _TelemetrySensorType.ValueType # 26 + """ + BMP3XX High accuracy temperature and pressure + """ + ICM20948: _TelemetrySensorType.ValueType # 27 + """ + ICM-20948 9-Axis digital motion processor + """ + MAX17048: _TelemetrySensorType.ValueType # 28 + """ + MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -237,6 +249,18 @@ NAU7802: TelemetrySensorType.ValueType # 25 """ NAU7802 Scale Chip or compatible """ +BMP3XX: TelemetrySensorType.ValueType # 26 +""" +BMP3XX High accuracy temperature and pressure +""" +ICM20948: TelemetrySensorType.ValueType # 27 +""" +ICM-20948 9-Axis digital motion processor +""" +MAX17048: TelemetrySensorType.ValueType # 28 +""" +MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) +""" global___TelemetrySensorType = TelemetrySensorType @typing.final @@ -275,13 +299,24 @@ class DeviceMetrics(google.protobuf.message.Message): def __init__( self, *, - battery_level: builtins.int = ..., - voltage: builtins.float = ..., - channel_utilization: builtins.float = ..., - air_util_tx: builtins.float = ..., - uptime_seconds: builtins.int = ..., + battery_level: builtins.int | None = ..., + voltage: builtins.float | None = ..., + channel_utilization: builtins.float | None = ..., + air_util_tx: builtins.float | None = ..., + uptime_seconds: builtins.int | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["air_util_tx", b"air_util_tx", "battery_level", b"battery_level", "channel_utilization", b"channel_utilization", "uptime_seconds", b"uptime_seconds", "voltage", b"voltage"]) -> None: ... + def HasField(self, field_name: typing.Literal["_air_util_tx", b"_air_util_tx", "_battery_level", b"_battery_level", "_channel_utilization", b"_channel_utilization", "_uptime_seconds", b"_uptime_seconds", "_voltage", b"_voltage", "air_util_tx", b"air_util_tx", "battery_level", b"battery_level", "channel_utilization", b"channel_utilization", "uptime_seconds", b"uptime_seconds", "voltage", b"voltage"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_air_util_tx", b"_air_util_tx", "_battery_level", b"_battery_level", "_channel_utilization", b"_channel_utilization", "_uptime_seconds", b"_uptime_seconds", "_voltage", b"_voltage", "air_util_tx", b"air_util_tx", "battery_level", b"battery_level", "channel_utilization", b"channel_utilization", "uptime_seconds", b"uptime_seconds", "voltage", b"voltage"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_air_util_tx", b"_air_util_tx"]) -> typing.Literal["air_util_tx"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_battery_level", b"_battery_level"]) -> typing.Literal["battery_level"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_channel_utilization", b"_channel_utilization"]) -> typing.Literal["channel_utilization"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_uptime_seconds", b"_uptime_seconds"]) -> typing.Literal["uptime_seconds"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voltage", b"_voltage"]) -> typing.Literal["voltage"] | None: ... global___DeviceMetrics = DeviceMetrics @@ -383,25 +418,60 @@ class EnvironmentMetrics(google.protobuf.message.Message): def __init__( self, *, - temperature: builtins.float = ..., - relative_humidity: builtins.float = ..., - barometric_pressure: builtins.float = ..., - gas_resistance: builtins.float = ..., - voltage: builtins.float = ..., - current: builtins.float = ..., - iaq: builtins.int = ..., - distance: builtins.float = ..., - lux: builtins.float = ..., - white_lux: builtins.float = ..., - ir_lux: builtins.float = ..., - uv_lux: builtins.float = ..., - wind_direction: builtins.int = ..., - wind_speed: builtins.float = ..., - weight: builtins.float = ..., - wind_gust: builtins.float = ..., - wind_lull: builtins.float = ..., + temperature: builtins.float | None = ..., + relative_humidity: builtins.float | None = ..., + barometric_pressure: builtins.float | None = ..., + gas_resistance: builtins.float | None = ..., + voltage: builtins.float | None = ..., + current: builtins.float | None = ..., + iaq: builtins.int | None = ..., + distance: builtins.float | None = ..., + lux: builtins.float | None = ..., + white_lux: builtins.float | None = ..., + ir_lux: builtins.float | None = ..., + uv_lux: builtins.float | None = ..., + wind_direction: builtins.int | None = ..., + wind_speed: builtins.float | None = ..., + weight: builtins.float | None = ..., + wind_gust: builtins.float | None = ..., + wind_lull: builtins.float | None = ..., ) -> None: ... - 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", "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: ... + 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", "_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", "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", "_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", "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 + def WhichOneof(self, oneof_group: typing.Literal["_current", b"_current"]) -> typing.Literal["current"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_distance", b"_distance"]) -> typing.Literal["distance"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_gas_resistance", b"_gas_resistance"]) -> typing.Literal["gas_resistance"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_iaq", b"_iaq"]) -> typing.Literal["iaq"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ir_lux", b"_ir_lux"]) -> typing.Literal["ir_lux"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_lux", b"_lux"]) -> typing.Literal["lux"] | None: ... + @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["_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: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voltage", b"_voltage"]) -> typing.Literal["voltage"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_weight", b"_weight"]) -> typing.Literal["weight"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_white_lux", b"_white_lux"]) -> typing.Literal["white_lux"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_wind_direction", b"_wind_direction"]) -> typing.Literal["wind_direction"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_wind_gust", b"_wind_gust"]) -> typing.Literal["wind_gust"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_wind_lull", b"_wind_lull"]) -> typing.Literal["wind_lull"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_wind_speed", b"_wind_speed"]) -> typing.Literal["wind_speed"] | None: ... global___EnvironmentMetrics = EnvironmentMetrics @@ -446,14 +516,27 @@ class PowerMetrics(google.protobuf.message.Message): def __init__( self, *, - ch1_voltage: builtins.float = ..., - ch1_current: builtins.float = ..., - ch2_voltage: builtins.float = ..., - ch2_current: builtins.float = ..., - ch3_voltage: builtins.float = ..., - ch3_current: builtins.float = ..., + ch1_voltage: builtins.float | None = ..., + ch1_current: builtins.float | None = ..., + ch2_voltage: builtins.float | None = ..., + ch2_current: builtins.float | None = ..., + ch3_voltage: builtins.float | None = ..., + ch3_current: builtins.float | None = ..., ) -> None: ... - 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"]) -> 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 + def WhichOneof(self, oneof_group: typing.Literal["_ch1_voltage", b"_ch1_voltage"]) -> typing.Literal["ch1_voltage"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ch2_current", b"_ch2_current"]) -> typing.Literal["ch2_current"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ch2_voltage", b"_ch2_voltage"]) -> typing.Literal["ch2_voltage"] | None: ... + @typing.overload + 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: ... global___PowerMetrics = PowerMetrics @@ -528,23 +611,112 @@ class AirQualityMetrics(google.protobuf.message.Message): def __init__( self, *, - pm10_standard: builtins.int = ..., - pm25_standard: builtins.int = ..., - pm100_standard: builtins.int = ..., - pm10_environmental: builtins.int = ..., - pm25_environmental: builtins.int = ..., - pm100_environmental: builtins.int = ..., - particles_03um: builtins.int = ..., - particles_05um: builtins.int = ..., - particles_10um: builtins.int = ..., - particles_25um: builtins.int = ..., - particles_50um: builtins.int = ..., - particles_100um: builtins.int = ..., + pm10_standard: builtins.int | None = ..., + pm25_standard: builtins.int | None = ..., + pm100_standard: builtins.int | None = ..., + pm10_environmental: builtins.int | None = ..., + pm25_environmental: builtins.int | None = ..., + pm100_environmental: builtins.int | None = ..., + particles_03um: builtins.int | None = ..., + particles_05um: builtins.int | None = ..., + particles_10um: builtins.int | None = ..., + particles_25um: builtins.int | None = ..., + particles_50um: builtins.int | None = ..., + particles_100um: builtins.int | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["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: ... + def HasField(self, field_name: typing.Literal["_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", "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["_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", "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["_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: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_particles_100um", b"_particles_100um"]) -> typing.Literal["particles_100um"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_particles_10um", b"_particles_10um"]) -> typing.Literal["particles_10um"] | None: ... + @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_50um", b"_particles_50um"]) -> typing.Literal["particles_50um"] | 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: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_pm10_environmental", b"_pm10_environmental"]) -> typing.Literal["pm10_environmental"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_pm10_standard", b"_pm10_standard"]) -> typing.Literal["pm10_standard"] | None: ... + @typing.overload + 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: ... global___AirQualityMetrics = AirQualityMetrics +@typing.final +class LocalStats(google.protobuf.message.Message): + """ + Local device mesh statistics + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UPTIME_SECONDS_FIELD_NUMBER: builtins.int + CHANNEL_UTILIZATION_FIELD_NUMBER: builtins.int + AIR_UTIL_TX_FIELD_NUMBER: builtins.int + NUM_PACKETS_TX_FIELD_NUMBER: builtins.int + NUM_PACKETS_RX_FIELD_NUMBER: builtins.int + NUM_PACKETS_RX_BAD_FIELD_NUMBER: builtins.int + NUM_ONLINE_NODES_FIELD_NUMBER: builtins.int + NUM_TOTAL_NODES_FIELD_NUMBER: builtins.int + uptime_seconds: builtins.int + """ + How long the device has been running since the last reboot (in seconds) + """ + channel_utilization: builtins.float + """ + Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). + """ + air_util_tx: builtins.float + """ + Percent of airtime for transmission used within the last hour. + """ + num_packets_tx: builtins.int + """ + Number of packets sent + """ + num_packets_rx: builtins.int + """ + Number of packets received good + """ + num_packets_rx_bad: builtins.int + """ + Number of packets received that are malformed or violate the protocol + """ + num_online_nodes: builtins.int + """ + Number of nodes online (in the past 2 hours) + """ + num_total_nodes: builtins.int + """ + Number of nodes total + """ + def __init__( + self, + *, + uptime_seconds: builtins.int = ..., + channel_utilization: builtins.float = ..., + air_util_tx: builtins.float = ..., + num_packets_tx: builtins.int = ..., + num_packets_rx: builtins.int = ..., + num_packets_rx_bad: builtins.int = ..., + num_online_nodes: builtins.int = ..., + num_total_nodes: builtins.int = ..., + ) -> 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_total_nodes", b"num_total_nodes", "uptime_seconds", b"uptime_seconds"]) -> None: ... + +global___LocalStats = LocalStats + @typing.final class Telemetry(google.protobuf.message.Message): """ @@ -558,6 +730,7 @@ class Telemetry(google.protobuf.message.Message): ENVIRONMENT_METRICS_FIELD_NUMBER: builtins.int AIR_QUALITY_METRICS_FIELD_NUMBER: builtins.int POWER_METRICS_FIELD_NUMBER: builtins.int + LOCAL_STATS_FIELD_NUMBER: builtins.int time: builtins.int """ Seconds since 1970 - or 0 for unknown/unset @@ -586,6 +759,12 @@ class Telemetry(google.protobuf.message.Message): Power Metrics """ + @property + def local_stats(self) -> global___LocalStats: + """ + Local device mesh statistics + """ + def __init__( self, *, @@ -594,10 +773,11 @@ class Telemetry(google.protobuf.message.Message): environment_metrics: global___EnvironmentMetrics | None = ..., air_quality_metrics: global___AirQualityMetrics | None = ..., power_metrics: global___PowerMetrics | None = ..., + local_stats: global___LocalStats | 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", "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", "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"] | 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", "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", "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"] | None: ... global___Telemetry = Telemetry diff --git a/protobufs b/protobufs index b1a79d5..b15c081 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b1a79d5db00f6aeeb0bbae156e8939e146c95299 +Subproject commit b15c081cb314c7407205ebe98b0f6d4345ae80bd From 58466f2ab77ab783f3976202a2505d398784c9d7 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 22:11:45 -0700 Subject: [PATCH 178/248] Add wiring for security config in node.py --- meshtastic/node.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meshtastic/node.py b/meshtastic/node.py index 48b9508..1a34ea0 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -170,6 +170,8 @@ class Node: p.set_config.lora.CopyFrom(self.localConfig.lora) elif config_name == "bluetooth": p.set_config.bluetooth.CopyFrom(self.localConfig.bluetooth) + elif config_name == "security": + p.set_config.security.CopyFrom(self.localConfig.security) elif config_name == "mqtt": p.set_module_config.mqtt.CopyFrom(self.moduleConfig.mqtt) elif config_name == "serial": From 477690edde5ae691c98c78ad1c7f82f994d84e94 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 21 Aug 2024 22:27:18 -0700 Subject: [PATCH 179/248] mark protobufs folder as generated code for github --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 5840970..2149e5d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ *.{cmd,[cC][mM][dD]} text eol=crlf *.{bat,[bB][aA][tT]} text eol=crlf *.{sh,[sS][hH]} text eol=lf +meshtastic/protobuf/* linguist-generated=true From c8cf8094c32a0de4ee11d0489e69b6e3d861c6b3 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Fri, 23 Aug 2024 13:18:23 -0700 Subject: [PATCH 180/248] randomize packet IDs as firmware does --- meshtastic/mesh_interface.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index c83a399..6ee292e 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -802,7 +802,10 @@ class MeshInterface: # pylint: disable=R0902 "Not connected yet, can not generate packet" ) else: - self.currentPacketId = (self.currentPacketId + 1) & 0xFFFFFFFF + nextPacketId = (self.currentPacketId + 1) & 0xFFFFFFFF + nextPacketId = nextPacketId & (0xFFFFFFFF >> 22) # mask upper 22 bits + randomPart = (random.randint(0, 0x7FFFFFFF) << 10) & 0xFFFFFFFF # generate number with 10 zeros at end + self.currentPacketId = nextPacketId | randomPart # combine return self.currentPacketId def _disconnected(self): From 1bbcc452ae13de5401d1d50153f0480a828333ba Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Fri, 23 Aug 2024 15:34:25 -0700 Subject: [PATCH 181/248] precalculate bit-shifts and don't generate too-large random numbers for packet ID generation --- meshtastic/mesh_interface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 6ee292e..fa2781a 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -803,9 +803,9 @@ class MeshInterface: # pylint: disable=R0902 ) else: nextPacketId = (self.currentPacketId + 1) & 0xFFFFFFFF - nextPacketId = nextPacketId & (0xFFFFFFFF >> 22) # mask upper 22 bits - randomPart = (random.randint(0, 0x7FFFFFFF) << 10) & 0xFFFFFFFF # generate number with 10 zeros at end - self.currentPacketId = nextPacketId | randomPart # combine + nextPacketId = nextPacketId & 0x3FF # == (0xFFFFFFFF >> 22), masks upper 22 bits + randomPart = (random.randint(0, 0x3FFFFF) << 10) & 0xFFFFFFFF # generate number with 10 zeros at end + self.currentPacketId = nextPacketId | randomPart # combine return self.currentPacketId def _disconnected(self): From 15b5e935638c86252c91fffcd2d93ab152d78855 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 23 Aug 2024 22:21:54 -0500 Subject: [PATCH 182/248] Correctly format public key and add to node list --- meshtastic/mesh_interface.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index fa2781a..d6bbe0f 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -260,6 +260,7 @@ class MeshInterface: # pylint: disable=R0902 "AKA": user.get("shortName", "N/A"), "ID": user["id"], "Hardware": user.get("hwModel", "UNSET"), + "Pubkey": user.get("publicKey", "UNSET"), } ) @@ -782,6 +783,13 @@ class MeshInterface: # pylint: disable=R0902 return user.get("shortName", None) return None + def getPublicKey(self): + """Get Public Key""" + user = self.getMyUser() + if user is not None: + return user.get("publicKey", None) + return None + def _waitConnected(self, timeout=30.0): """Block until the initial node db download is complete, or timeout and raise an exception""" @@ -1066,7 +1074,10 @@ class MeshInterface: # pylint: disable=R0902 self.localNode.localConfig.bluetooth.CopyFrom( fromRadio.config.bluetooth ) - + elif fromRadio.config.HasField("security"): + self.localNode.localConfig.security.CopyFrom( + fromRadio.config.security + ) elif fromRadio.moduleConfig.HasField("mqtt"): self.localNode.moduleConfig.mqtt.CopyFrom(fromRadio.moduleConfig.mqtt) elif fromRadio.moduleConfig.HasField("serial"): From 216fd7ddc43cfbb9915f5abd92c8fb0789bd3708 Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Sat, 24 Aug 2024 10:07:48 +0200 Subject: [PATCH 183/248] Show two-way traceroute result with SNR if available --- meshtastic/mesh_interface.py | 53 +++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index d6bbe0f..23c5fac 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -548,17 +548,46 @@ class MeshInterface: # pylint: disable=R0902 def onResponseTraceRoute(self, p: dict): """on response for trace route""" + UNK_SNR = -128 # Value representing unknown SNR + routeDiscovery = mesh_pb2.RouteDiscovery() routeDiscovery.ParseFromString(p["decoded"]["payload"]) asDict = google.protobuf.json_format.MessageToDict(routeDiscovery) - print("Route traced:") - routeStr = self._nodeNumToId(p["to"]) or f"{p['to']:08x}" - if "route" in asDict: - for nodeNum in asDict["route"]: - routeStr += " --> " + (self._nodeNumToId(nodeNum) or f"{nodeNum:08x}") - routeStr += " --> " + (self._nodeNumToId(p["from"]) or f"{p['from']:08x}") - print(routeStr) + print("Route traced towards destination:") + routeStr = self._nodeNumToId(p["to"], False) or f"{p['to']:08x}" # Start with destination of response + + # SNR list should have one more entry than the route, as the final destination adds its SNR also + lenTowards = 0 if "route" not in asDict else len(asDict["route"]) + snrTowardsValid = "snrTowards" in asDict and len(asDict["snrTowards"]) == lenTowards + 1 + if lenTowards > 0: # Loop through hops in route and add SNR if available + for idx, nodeNum in enumerate(asDict["route"]): + routeStr += " --> " + (self._nodeNumToId(nodeNum, False) or f"{nodeNum:08x}") \ + + " (" + (str(asDict["snrTowards"][idx] / 4) if snrTowardsValid and asDict["snrTowards"][idx] != UNK_SNR else "?") + "dB)" + + # End with origin of response + routeStr += " --> " + (self._nodeNumToId(p["from"], False) or f"{p['from']:08x}") \ + + " (" + (str(asDict["snrTowards"][-1] / 4) if snrTowardsValid and asDict["snrTowards"][-1] != UNK_SNR else "?") + "dB)" + + print(routeStr) # Print the route towards destination + + # Only if there is an SNR entry (for the origin) it's valid, even though route might be empty (direct connection) + lenBack = 0 if "routeBack" not in asDict else len(asDict["routeBack"]) + backValid = "snrBack" in asDict and len(asDict["snrBack"]) == lenBack + 1 + if backValid: + print("Route traced back to us:") + routeStr = self._nodeNumToId(p["from"], False) or f"{p['from']:08x}" # Start with origin of response + + if lenBack > 0: # Loop through hops in routeBack and add SNR if available + for idx, nodeNum in enumerate(asDict["routeBack"]): + routeStr += " --> " + (self._nodeNumToId(nodeNum, False) or f"{nodeNum:08x}") \ + + " (" + (str(asDict["snrBack"][idx] / 4) if asDict["snrBack"][idx] != UNK_SNR else "?") + "dB)" + + # End with destination of response (us) + routeStr += " --> " + (self._nodeNumToId(p["to"], False) or f"{p['to']:08x}") \ + + " (" + (str(asDict["snrBack"][-1] / 4) if asDict["snrBack"][-1] != UNK_SNR else "?") + "dB)" + + print(routeStr) # Print the route back to us self._acknowledgment.receivedTraceRoute = True @@ -1143,17 +1172,21 @@ class MeshInterface: # pylint: disable=R0902 position["longitude"] = float(position["longitudeI"] * Decimal("1e-7")) return position - def _nodeNumToId(self, num: int) -> Optional[str]: + def _nodeNumToId(self, num: int, isDest = True) -> Optional[str]: """Map a node node number to a node ID Arguments: num {int} -- Node number + isDest {bool} -- True if the node number is a destination (to show broadcast address or unknown node) Returns: string -- Node ID """ if num == BROADCAST_NUM: - return BROADCAST_ADDR + if isDest: + return BROADCAST_ADDR + else: + return "Unknown" try: return self.nodesByNum[num]["user"]["id"] # type: ignore[index] @@ -1226,7 +1259,7 @@ class MeshInterface: # pylint: disable=R0902 # /add fromId and toId fields based on the node ID try: - asDict["fromId"] = self._nodeNumToId(asDict["from"]) + asDict["fromId"] = self._nodeNumToId(asDict["from"], False) except Exception as ex: logging.warning(f"Not populating fromId {ex}") try: From 78399503c54985b1d68ddbec3373a91781c2b982 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 24 Aug 2024 15:32:44 -0500 Subject: [PATCH 184/248] Adds handlers to get and set admin session_key for remote admin --- meshtastic/__init__.py | 10 ++++++++++ meshtastic/node.py | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index f4d91fd..6ffc3d7 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -199,6 +199,13 @@ def _receiveInfoUpdate(iface, asDict): iface._getOrCreateByNum(asDict["from"])["snr"] = asDict.get("rxSnr") iface._getOrCreateByNum(asDict["from"])["hopLimit"] = asDict.get("hopLimit") +def _onAdminReceive(iface, asDict): + """Special auto parsing for received messages""" + logging.debug(f"in _onAdminReceive() asDict:{asDict}") + if "decoded" in asDict: + if "admin" in asDict["decoded"] and "from" in asDict: + adminMessage: admin_pb2.AdminMessage = asDict["decoded"]["admin"] + iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage["raw"].session_passkey """Well known message payloads can register decoders for automatic protobuf parsing""" protocols = { @@ -238,4 +245,7 @@ protocols = { portnums_pb2.PortNum.STORE_FORWARD_APP: KnownProtocol("storeforward", storeforward_pb2.StoreAndForward), portnums_pb2.PortNum.NEIGHBORINFO_APP: KnownProtocol("neighborinfo", mesh_pb2.NeighborInfo), portnums_pb2.PortNum.MAP_REPORT_APP: KnownProtocol("mapreport", mqtt_pb2.MapReport), + portnums_pb2.PortNum.ADMIN_APP: KnownProtocol( + "admin", admin_pb2.AdminMessage, _onAdminReceive + ), } diff --git a/meshtastic/node.py b/meshtastic/node.py index 1a34ea0..da1f517 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -95,7 +95,7 @@ class Node: else: self.iface._acknowledgment.receivedAck = True print("") - adminMessage = p["decoded"]["admin"] + adminMessage: admin_pb2.AdminMessage = p["decoded"]["admin"] if "getConfigResponse" in adminMessage: resp = adminMessage["getConfigResponse"] field = list(resp.keys())[0] @@ -833,7 +833,12 @@ class Node: ): # unless a special channel index was used, we want to use the admin index adminIndex = self.iface.localNode._getAdminChannelIndex() logging.debug(f"adminIndex:{adminIndex}") - + if isinstance(self.nodeNum, int): + nodeid = self.nodeNum + elif self.nodeNum.startswith("!"): + 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, From bc508ff9e6005392950b841a83906ae4d37f55af Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 14:15:37 -0700 Subject: [PATCH 185/248] cleanup admin stuff a little --- meshtastic/__init__.py | 14 ++++++-------- meshtastic/node.py | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 6ffc3d7..64f8227 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -202,10 +202,9 @@ def _receiveInfoUpdate(iface, asDict): def _onAdminReceive(iface, asDict): """Special auto parsing for received messages""" logging.debug(f"in _onAdminReceive() asDict:{asDict}") - if "decoded" in asDict: - if "admin" in asDict["decoded"] and "from" in asDict: - adminMessage: admin_pb2.AdminMessage = asDict["decoded"]["admin"] - iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage["raw"].session_passkey + if "decoded" in asDict and "from" in asDict and "admin" in asDict["decoded"] + adminMessage: admin_pb2.AdminMessage = asDict["decoded"]["admin"]["raw"] + iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage.session_passkey """Well known message payloads can register decoders for automatic protobuf parsing""" protocols = { @@ -225,7 +224,9 @@ protocols = { portnums_pb2.PortNum.NODEINFO_APP: KnownProtocol( "user", mesh_pb2.User, _onNodeInfoReceive ), - portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage), + portnums_pb2.PortNum.ADMIN_APP: KnownProtocol( + "admin", admin_pb2.AdminMessage, _onAdminReceive + ), portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing), portnums_pb2.PortNum.TELEMETRY_APP: KnownProtocol( "telemetry", telemetry_pb2.Telemetry @@ -245,7 +246,4 @@ protocols = { portnums_pb2.PortNum.STORE_FORWARD_APP: KnownProtocol("storeforward", storeforward_pb2.StoreAndForward), portnums_pb2.PortNum.NEIGHBORINFO_APP: KnownProtocol("neighborinfo", mesh_pb2.NeighborInfo), portnums_pb2.PortNum.MAP_REPORT_APP: KnownProtocol("mapreport", mqtt_pb2.MapReport), - portnums_pb2.PortNum.ADMIN_APP: KnownProtocol( - "admin", admin_pb2.AdminMessage, _onAdminReceive - ), } diff --git a/meshtastic/node.py b/meshtastic/node.py index da1f517..d6e2432 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -95,7 +95,7 @@ class Node: else: self.iface._acknowledgment.receivedAck = True print("") - adminMessage: admin_pb2.AdminMessage = p["decoded"]["admin"] + adminMessage = p["decoded"]["admin"] if "getConfigResponse" in adminMessage: resp = adminMessage["getConfigResponse"] field = list(resp.keys())[0] From 4cc283d0041a75c6958603efa896e57f31b94ac4 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 24 Aug 2024 17:27:42 -0500 Subject: [PATCH 186/248] Add the admin sessionkey_only request --- meshtastic/__main__.py | 8 ++++++-- meshtastic/node.py | 29 +++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index e7886e6..0722c34 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -39,7 +39,7 @@ except ImportError as e: have_powermon = False powermon_exception = e meter = None -from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 +from meshtastic.protobuf import admin_pb2, channel_pb2, config_pb2, portnums_pb2 from meshtastic.version import get_active_version def onReceive(packet, interface): @@ -334,7 +334,11 @@ def onConnected(interface): closeNow = True waitForAckNak = True print(f"Setting device owner to {args.set_owner}") - interface.getNode(args.dest, False).setOwner(args.set_owner) + node = interface.getNode(args.dest, False) + node.requestConfig( + admin_pb2.AdminMessage.SESSIONKEY_CONFIG + ) + node.setOwner(args.set_owner) if args.set_owner_short: closeNow = True diff --git a/meshtastic/node.py b/meshtastic/node.py index d6e2432..cb5f29b 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -88,6 +88,7 @@ class Node: def onResponseRequestSettings(self, p): """Handle the response packets for requesting settings _requestSettings()""" logging.debug(f"onResponseRequestSetting() p:{p}") + config_values = None if "routing" in p["decoded"]: if p["decoded"]["routing"]["errorReason"] != "NONE": print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}') @@ -102,7 +103,8 @@ class Node: config_type = self.localConfig.DESCRIPTOR.fields_by_name.get( camel_to_snake(field) ) - config_values = getattr(self.localConfig, config_type.name) + if config_type is not None: + config_values = getattr(self.localConfig, config_type.name) elif "getModuleConfigResponse" in adminMessage: resp = adminMessage["getModuleConfigResponse"] field = list(resp.keys())[0] @@ -115,9 +117,10 @@ class Node: "Did not receive a valid response. Make sure to have a shared channel named 'admin'." ) return - for key, value in resp[field].items(): - setattr(config_values, camel_to_snake(key), value) - print(f"{str(camel_to_snake(field))}:\n{str(config_values)}") + if config_values is not None: + for key, value in resp[field].items(): + setattr(config_values, camel_to_snake(key), value) + print(f"{str(camel_to_snake(field))}:\n{str(config_values)}") def requestConfig(self, configType): """Request the config from the node via admin message""" @@ -126,16 +129,18 @@ class Node: else: onResponse = self.onResponseRequestSettings print("Requesting current config from remote node (this can take a while).") + p = admin_pb2.AdminMessage() + if isinstance(configType, int): + p.get_config_request = configType - msgIndex = configType.index - if configType.containing_type.name == "LocalConfig": - p = admin_pb2.AdminMessage() - p.get_config_request = msgIndex - self._sendAdmin(p, wantResponse=True, onResponse=onResponse) else: - p = admin_pb2.AdminMessage() - p.get_module_config_request = msgIndex - self._sendAdmin(p, wantResponse=True, onResponse=onResponse) + msgIndex = configType.index + if configType.containing_type.name == "LocalConfig": + p.get_config_request = msgIndex + else: + p.get_module_config_request = msgIndex + + self._sendAdmin(p, wantResponse=True, onResponse=onResponse) if onResponse: self.iface.waitForAckNak() From eec745c86116f4ffe553dd7d17673c2d218dd238 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 24 Aug 2024 19:29:18 -0500 Subject: [PATCH 187/248] Add missed colon in if statement --- meshtastic/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 64f8227..d815464 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -202,7 +202,7 @@ def _receiveInfoUpdate(iface, asDict): def _onAdminReceive(iface, asDict): """Special auto parsing for received messages""" logging.debug(f"in _onAdminReceive() asDict:{asDict}") - if "decoded" in asDict and "from" in asDict and "admin" in asDict["decoded"] + if "decoded" in asDict and "from" in asDict and "admin" in asDict["decoded"]: adminMessage: admin_pb2.AdminMessage = asDict["decoded"]["admin"]["raw"] iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage.session_passkey From a9e2168f1d3b64daf99ba1b02644c8a36bc5abe2 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 24 Aug 2024 20:18:57 -0500 Subject: [PATCH 188/248] Refactor to add ensureSessionKey function --- meshtastic/__main__.py | 8 ++------ meshtastic/node.py | 26 +++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 0722c34..e7886e6 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -39,7 +39,7 @@ except ImportError as e: have_powermon = False powermon_exception = e meter = None -from meshtastic.protobuf import admin_pb2, channel_pb2, config_pb2, portnums_pb2 +from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2 from meshtastic.version import get_active_version def onReceive(packet, interface): @@ -334,11 +334,7 @@ def onConnected(interface): closeNow = True waitForAckNak = True print(f"Setting device owner to {args.set_owner}") - node = interface.getNode(args.dest, False) - node.requestConfig( - admin_pb2.AdminMessage.SESSIONKEY_CONFIG - ) - node.setOwner(args.set_owner) + interface.getNode(args.dest, False).setOwner(args.set_owner) if args.set_owner_short: closeNow = True diff --git a/meshtastic/node.py b/meshtastic/node.py index cb5f29b..10c673c 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -221,7 +221,7 @@ class Node: def writeChannel(self, channelIndex, adminIndex=0): """Write the current (edited) channel to the device""" - + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.set_channel.CopyFrom(self.channels[channelIndex]) self._sendAdmin(p, adminIndex=adminIndex) @@ -289,6 +289,7 @@ class Node: def setOwner(self, long_name=None, short_name=None, is_licensed=False): """Set device owner name""" logging.debug(f"in setOwner nodeNum:{self.nodeNum}") + self.ensureSessionKey() p = admin_pb2.AdminMessage() nChars = 4 @@ -422,7 +423,7 @@ class Node: if len(ringtone) > 230: our_exit("Warning: The ringtone must be less than 230 characters.") - + self.ensureSessionKey() # split into chunks chunks = [] chunks_size = 230 @@ -498,7 +499,7 @@ class Node: if len(message) > 200: our_exit("Warning: The canned message must be less than 200 characters.") - + self.ensureSessionKey() # split into chunks chunks = [] chunks_size = 200 @@ -525,6 +526,7 @@ class Node: def exitSimulator(self): """Tell a simulator node to exit (this message is ignored for other nodes)""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.exit_simulator = True logging.debug("in exitSimulator()") @@ -533,6 +535,7 @@ class Node: def reboot(self, secs: int = 10): """Tell the node to reboot.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.reboot_seconds = secs logging.info(f"Telling node to reboot in {secs} seconds") @@ -546,6 +549,7 @@ class Node: def beginSettingsTransaction(self): """Tell the node to open a transaction to edit settings.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.begin_edit_settings = True logging.info(f"Telling open a transaction to edit settings") @@ -559,6 +563,7 @@ class Node: def commitSettingsTransaction(self): """Tell the node to commit the open transaction for editing settings.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.commit_edit_settings = True logging.info(f"Telling node to commit open transaction for editing settings") @@ -572,6 +577,7 @@ class Node: def rebootOTA(self, secs: int = 10): """Tell the node to reboot into factory firmware.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.reboot_ota_seconds = secs logging.info(f"Telling node to reboot to OTA in {secs} seconds") @@ -585,6 +591,7 @@ class Node: def enterDFUMode(self): """Tell the node to enter DFU mode (NRF52).""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.enter_dfu_mode_request = True logging.info(f"Telling node to enable DFU mode") @@ -598,6 +605,7 @@ class Node: def shutdown(self, secs: int = 10): """Tell the node to shutdown.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.shutdown_seconds = secs logging.info(f"Telling node to shutdown in {secs} seconds") @@ -622,6 +630,7 @@ class Node: def factoryReset(self): """Tell the node to factory reset.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.factory_reset = True logging.info(f"Telling node to factory reset") @@ -635,6 +644,7 @@ class Node: def removeNode(self, nodeId: Union[int, str]): """Tell the node to remove a specific node by ID""" + self.ensureSessionKey() if isinstance(nodeId, str): if nodeId.startswith("!"): nodeId = int(nodeId[1:], 16) @@ -652,6 +662,7 @@ class Node: def resetNodeDb(self): """Tell the node to reset its list of nodes.""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.nodedb_reset = True logging.info(f"Telling node to reset the NodeDB") @@ -689,6 +700,7 @@ class Node: def removeFixedPosition(self): """Tell the node to remove the fixed position and set the fixed position setting to false""" + self.ensureSessionKey() p = admin_pb2.AdminMessage() p.remove_fixed_position = True logging.info(f"Telling node to remove fixed position") @@ -853,3 +865,11 @@ class Node: onResponse=onResponse, channelIndex=adminIndex, ) + + def ensureSessionKey(self): + if isinstance(self.nodeNum, int): + nodeid = self.nodeNum + elif self.nodeNum.startswith("!"): + nodeid = int(self.nodeNum[1:],16) + if self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey") is None: + self.requestConfig(admin_pb2.AdminMessage.SESSIONKEY_CONFIG) \ No newline at end of file From dfa29bbb7cbf01041e6548dc06f57386dabe9dc5 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 21:50:44 -0700 Subject: [PATCH 189/248] Add ensureSessionKey to setURL and setFixedPosition calls --- meshtastic/node.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meshtastic/node.py b/meshtastic/node.py index 10c673c..fff8f8d 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -375,6 +375,7 @@ class Node: p = admin_pb2.AdminMessage() p.set_config.lora.CopyFrom(channelSet.lora_config) + self.ensureSessionKey() self._sendAdmin(p) def onResponseRequestRingtone(self, p): @@ -676,6 +677,7 @@ class Node: def setFixedPosition(self, lat: Union[int, float], lon: Union[int, float], alt: int): """Tell the node to set fixed position to the provided value and enable the fixed position setting""" + self.ensureSessionKey() if self != self.iface.localNode: logging.error("Setting position of remote nodes is not supported.") return None @@ -872,4 +874,4 @@ class Node: elif self.nodeNum.startswith("!"): nodeid = int(self.nodeNum[1:],16) if self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey") is None: - self.requestConfig(admin_pb2.AdminMessage.SESSIONKEY_CONFIG) \ No newline at end of file + self.requestConfig(admin_pb2.AdminMessage.SESSIONKEY_CONFIG) From e7ed254d9d65ba3eecb2739428cc66383b872dc4 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 22:00:29 -0700 Subject: [PATCH 190/248] appease pylint, tests, mypy --- meshtastic/__init__.py | 2 +- meshtastic/node.py | 22 ++++++++++++++-------- meshtastic/tests/test_node.py | 12 +++++++++--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index d815464..51fba08 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -203,7 +203,7 @@ def _onAdminReceive(iface, asDict): """Special auto parsing for received messages""" logging.debug(f"in _onAdminReceive() asDict:{asDict}") if "decoded" in asDict and "from" in asDict and "admin" in asDict["decoded"]: - adminMessage: admin_pb2.AdminMessage = asDict["decoded"]["admin"]["raw"] + adminMessage = asDict["decoded"]["admin"]["raw"] iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage.session_passkey """Well known message payloads can register decoders for automatic protobuf parsing""" diff --git a/meshtastic/node.py b/meshtastic/node.py index fff8f8d..69f9058 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -854,9 +854,9 @@ class Node: logging.debug(f"adminIndex:{adminIndex}") if isinstance(self.nodeNum, int): nodeid = self.nodeNum - elif self.nodeNum.startswith("!"): + else: # assume string starting with ! nodeid = int(self.nodeNum[1:],16) - if ("adminSessionPassKey" in self.iface._getOrCreateByNum(nodeid)): + if "adminSessionPassKey" in self.iface._getOrCreateByNum(nodeid): p.session_passkey = self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey") return self.iface.sendData( p, @@ -869,9 +869,15 @@ class Node: ) def ensureSessionKey(self): - if isinstance(self.nodeNum, int): - nodeid = self.nodeNum - elif self.nodeNum.startswith("!"): - nodeid = int(self.nodeNum[1:],16) - if self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey") is None: - self.requestConfig(admin_pb2.AdminMessage.SESSIONKEY_CONFIG) + """If our entry in iface.nodesByNum doesn't already have an adminSessionPassKey, make a request to get one""" + if self.noProto: + logging.warning( + f"Not ensuring session key, because protocol use is disabled by noProto" + ) + else: + 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) diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index df3dffb..5361296 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -231,7 +231,9 @@ def test_node(capsys): @pytest.mark.unit def test_exitSimulator(caplog): """Test exitSimulator""" - anode = Node("foo", "bar", noProto=True) + interface = MeshInterface() + interface.nodesByNum = {} + anode = Node(interface, "!ba400000", noProto=True) with caplog.at_level(logging.DEBUG): anode.exitSimulator() assert re.search(r"in exitSimulator", caplog.text, re.MULTILINE) @@ -240,7 +242,9 @@ def test_exitSimulator(caplog): @pytest.mark.unit def test_reboot(caplog): """Test reboot""" - anode = Node(MeshInterface(), 1234567890, noProto=True) + interface = MeshInterface() + interface.nodesByNum = {} + anode = Node(interface, 1234567890, noProto=True) with caplog.at_level(logging.DEBUG): anode.reboot() assert re.search(r"Telling node to reboot", caplog.text, re.MULTILINE) @@ -249,7 +253,9 @@ def test_reboot(caplog): @pytest.mark.unit def test_shutdown(caplog): """Test shutdown""" - anode = Node(MeshInterface(), 1234567890, noProto=True) + interface = MeshInterface() + interface.nodesByNum = {} + anode = Node(interface, 1234567890, noProto=True) with caplog.at_level(logging.DEBUG): anode.shutdown() assert re.search(r"Telling node to shutdown", caplog.text, re.MULTILINE) From eedf42b904f403d16dd984544430d938581b0e3f Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 22:25:18 -0700 Subject: [PATCH 191/248] add more fuzzing tests for utility functions --- meshtastic/tests/test_util.py | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index 1ea80da..59f2d7e 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -594,3 +594,54 @@ def test_roundtrip_snake_to_camel_camel_to_snake(a_string): value0 = snake_to_camel(a_string=a_string) value1 = camel_to_snake(a_string=value0) assert a_string == value1, (a_string, value1) + +@given(st.text()) +def test_fuzz_camel_to_snake(a_string): + result = camel_to_snake(a_string) + assert "_" in result or result == a_string.lower() + +@given(st.text()) +def test_fuzz_snake_to_camel(a_string): + result = snake_to_camel(a_string) + assert "_" not in result or result == a_string.split("_")[0] + "".join(ele.title() for ele in a_string.split("_")[1:]) + +@given(st.text()) +def test_fuzz_stripnl(s): + result = stripnl(s) + assert "\n" not in result + +@given(st.binary()) +def test_fuzz_pskToString(psk): + result = pskToString(psk) + if len(psk) == 0: + assert result == "unencrypted" + elif len(psk) == 1: + b = psk[0] + if b == 0: + assert result == "unencrypted" + elif b == 1: + assert result == "default" + else: + assert result == f"simple{b - 1}" + else: + assert result == "secret" + +@given(st.text()) +def test_fuzz_fromStr(valstr): + result = fromStr(valstr) + if valstr.startswith("0x"): + assert isinstance(result, bytes) + elif valstr.startswith("base64:"): + assert isinstance(result, bytes) + elif len(valstr) == 0: + assert result == b'' + elif valstr.lower() in {"t", "true", "yes"}: + assert result is True + elif valstr.lower() in {"f", "false", "no"}: + assert result is False + else: + try: + int(valstr) + assert isinstance(result, int) + except ValueError: + assert isinstance(result, str) From df12b8a659f68e1ac6f341ad640587a32504e775 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 23:34:28 -0700 Subject: [PATCH 192/248] appease the pylint beast --- meshtastic/tests/test_util.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index 59f2d7e..e1930e6 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -597,21 +597,25 @@ def test_roundtrip_snake_to_camel_camel_to_snake(a_string): @given(st.text()) def test_fuzz_camel_to_snake(a_string): + """Test that camel_to_snake produces outputs with underscores for multi-word camelcase""" result = camel_to_snake(a_string) assert "_" in result or result == a_string.lower() @given(st.text()) def test_fuzz_snake_to_camel(a_string): + """Test that snake_to_camel removes underscores""" result = snake_to_camel(a_string) assert "_" not in result or result == a_string.split("_")[0] + "".join(ele.title() for ele in a_string.split("_")[1:]) @given(st.text()) def test_fuzz_stripnl(s): + """Test that stripnl always takes away newlines""" result = stripnl(s) assert "\n" not in result @given(st.binary()) def test_fuzz_pskToString(psk): + """Test that pskToString produces sane output for any bytes""" result = pskToString(psk) if len(psk) == 0: assert result == "unencrypted" @@ -628,6 +632,7 @@ def test_fuzz_pskToString(psk): @given(st.text()) def test_fuzz_fromStr(valstr): + """Test that fromStr produces mostly-useful output given any string""" result = fromStr(valstr) if valstr.startswith("0x"): assert isinstance(result, bytes) From 84dff753990702bfcaa1e532d5863f57905cf746 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 24 Aug 2024 23:38:48 -0700 Subject: [PATCH 193/248] allow for underscore-only stuff in camel_to_snake, silly as that is --- meshtastic/tests/test_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index e1930e6..09f67fe 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -599,7 +599,7 @@ def test_roundtrip_snake_to_camel_camel_to_snake(a_string): def test_fuzz_camel_to_snake(a_string): """Test that camel_to_snake produces outputs with underscores for multi-word camelcase""" result = camel_to_snake(a_string) - assert "_" in result or result == a_string.lower() + assert "_" in result or result == a_string.lower().replace("_", "") @given(st.text()) def test_fuzz_snake_to_camel(a_string): From e725292ee090cb40fd8eb5414c7d1be764ac0fd1 Mon Sep 17 00:00:00 2001 From: Wolfgang Nagele Date: Sun, 25 Aug 2024 14:39:37 +0200 Subject: [PATCH 194/248] Code block unreachable --- meshtastic/mesh_interface.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index c83a399..7401b0c 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -975,13 +975,6 @@ class MeshInterface: # pylint: disable=R0902 self.localNode.nodeNum = self.myInfo.my_node_num logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}") - failmsg = None - - if failmsg: - self.failure = MeshInterface.MeshInterfaceError(failmsg) - self.isConnected.set() # let waitConnected return this exception - self.close() - elif fromRadio.HasField("metadata"): self.metadata = fromRadio.metadata logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}") From b692ef4cfb6b1bef9b70c665c5c30e051240bde0 Mon Sep 17 00:00:00 2001 From: Wolfgang Nagele Date: Sun, 25 Aug 2024 11:11:10 +0200 Subject: [PATCH 195/248] Add method to be able to send heartbeat --- meshtastic/mesh_interface.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index c83a399..3948089 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -812,19 +812,21 @@ class MeshInterface: # pylint: disable=R0902 lambda: pub.sendMessage("meshtastic.connection.lost", interface=self) ) + def sendHeartbeat(self): + p = mesh_pb2.ToRadio() + p.heartbeat.CopyFrom(mesh_pb2.Heartbeat()) + self._sendToRadio(p) + def _startHeartbeat(self): """We need to send a heartbeat message to the device every X seconds""" def callback(): self.heartbeatTimer = None - i = 300 - logging.debug(f"Sending heartbeat, interval {i} seconds") - if i != 0: - self.heartbeatTimer = threading.Timer(i, callback) - self.heartbeatTimer.start() - p = mesh_pb2.ToRadio() - p.heartbeat.CopyFrom(mesh_pb2.Heartbeat()) - self._sendToRadio(p) + interval = 300 + logging.debug(f"Sending heartbeat, interval {interval} seconds") + self.heartbeatTimer = threading.Timer(interval, callback) + self.heartbeatTimer.start() + self.sendHeartbeat() callback() # run our periodic callback now, it will make another timer if necessary From d77335caa7fde9f2cd0585ab76a38f90213be250 Mon Sep 17 00:00:00 2001 From: Wolfgang Nagele Date: Sun, 25 Aug 2024 22:13:08 +0200 Subject: [PATCH 196/248] Add sendHeartbeat doc-string --- meshtastic/mesh_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 3948089..36c7ee8 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -813,6 +813,7 @@ class MeshInterface: # pylint: disable=R0902 ) def sendHeartbeat(self): + """Sends a heartbeat to the radio. Can be used to verify the connection is healthy.""" p = mesh_pb2.ToRadio() p.heartbeat.CopyFrom(mesh_pb2.Heartbeat()) self._sendToRadio(p) From b2acc847179a81d6814343b86c769a5276e15b42 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 25 Aug 2024 18:27:34 -0700 Subject: [PATCH 197/248] remove trailing whitespace --- meshtastic/mesh_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 23c5fac..2eb66f8 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -1185,7 +1185,7 @@ class MeshInterface: # pylint: disable=R0902 if num == BROADCAST_NUM: if isDest: return BROADCAST_ADDR - else: + else: return "Unknown" try: From c92474cf365b3bb06726cac4717892b1dce012d4 Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Mon, 26 Aug 2024 20:32:11 +0200 Subject: [PATCH 198/248] HopStart should be set for route back to be valid --- meshtastic/mesh_interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 2eb66f8..c061534 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -571,9 +571,9 @@ class MeshInterface: # pylint: disable=R0902 print(routeStr) # Print the route towards destination - # Only if there is an SNR entry (for the origin) it's valid, even though route might be empty (direct connection) + # Only if hopStart is set and there is an SNR entry (for the origin) it's valid, even though route might be empty (direct connection) lenBack = 0 if "routeBack" not in asDict else len(asDict["routeBack"]) - backValid = "snrBack" in asDict and len(asDict["snrBack"]) == lenBack + 1 + backValid = "hopStart" in p and "snrBack" in asDict and len(asDict["snrBack"]) == lenBack + 1 if backValid: print("Route traced back to us:") routeStr = self._nodeNumToId(p["from"], False) or f"{p['from']:08x}" # Start with origin of response From aedaa3748d9b71e75316bf1ac45dc4775c6a9c0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:23:54 +0000 Subject: [PATCH 199/248] Bump jupyterlab from 4.2.3 to 4.2.5 Bumps [jupyterlab](https://github.com/jupyterlab/jupyterlab) from 4.2.3 to 4.2.5. - [Release notes](https://github.com/jupyterlab/jupyterlab/releases) - [Changelog](https://github.com/jupyterlab/jupyterlab/blob/@jupyterlab/lsp@4.2.5/CHANGELOG.md) - [Commits](https://github.com/jupyterlab/jupyterlab/compare/@jupyterlab/lsp@4.2.3...@jupyterlab/lsp@4.2.5) --- updated-dependencies: - dependency-name: jupyterlab dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- poetry.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 28373e0..c1c3cae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "altgraph" @@ -1576,13 +1576,13 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.2.3" +version = "4.2.5" description = "JupyterLab computational environment" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.2.3-py3-none-any.whl", hash = "sha256:0b59d11808e84bb84105c73364edfa867dd475492429ab34ea388a52f2e2e596"}, - {file = "jupyterlab-4.2.3.tar.gz", hash = "sha256:df6e46969ea51d66815167f23d92f105423b7f1f06fa604d4f44aeb018c82c7b"}, + {file = "jupyterlab-4.2.5-py3-none-any.whl", hash = "sha256:73b6e0775d41a9fee7ee756c80f58a6bed4040869ccc21411dc559818874d321"}, + {file = "jupyterlab-4.2.5.tar.gz", hash = "sha256:ae7f3a1b8cb88b4f55009ce79fa7c06f99d70cd63601ee4aa91815d054f46f75"}, ] [package.dependencies] @@ -1607,7 +1607,7 @@ dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] -upgrade-extension = ["copier (>=8,<10)", "jinja2-time (<0.3)", "pydantic (<2.0)", "pyyaml-include (<2.0)", "tomli-w (<2.0)"] +upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] [[package]] name = "jupyterlab-pygments" @@ -2287,8 +2287,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -2845,8 +2845,8 @@ astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" From 4500850063e0852519265f0b2262ba092c3bc61f Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 29 Aug 2024 22:29:20 -0500 Subject: [PATCH 200/248] Don't automatically set the time from Python The Python MO is to do as little as possible beyond what the user has intentionally instructed. So don't try to set the time automatically. --- meshtastic/mesh_interface.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index c59fcb3..fd09e65 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -472,11 +472,6 @@ class MeshInterface: # pylint: disable=R0902 p.altitude = int(altitude) logging.debug(f"p.altitude:{p.altitude}") - if timeSec == 0: - timeSec = int(time.time()) # returns unix timestamp in seconds - p.time = timeSec - logging.debug(f"p.time:{p.time}") - if wantResponse: onResponse = self.onResponsePosition else: From 428e9a228c1c43e32e55f5e7d4597d4d877ecb4f Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 29 Aug 2024 23:09:04 -0500 Subject: [PATCH 201/248] Remove unused time variable --- meshtastic/mesh_interface.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index fd09e65..91a8c1f 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -442,7 +442,6 @@ class MeshInterface: # pylint: disable=R0902 latitude: float = 0.0, longitude: float = 0.0, altitude: int = 0, - timeSec: int = 0, destinationId: Union[int, str] = BROADCAST_ADDR, wantAck: bool = False, wantResponse: bool = False, @@ -454,8 +453,6 @@ class MeshInterface: # pylint: disable=R0902 Also, the device software will notice this packet and use it to automatically set its notion of the local position. - If timeSec is not specified (recommended), we will use the local machine time. - Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ From 5c312bedc190271b5c56d53967bb5097df2e1b2a Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 30 Aug 2024 01:15:40 -0500 Subject: [PATCH 202/248] Remove assert from test, due to removed position time --- meshtastic/tests/test_mesh_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index f637c62..21f80c6 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -185,7 +185,7 @@ def test_sendPosition(caplog): with caplog.at_level(logging.DEBUG): iface.sendPosition() iface.close() - assert re.search(r"p.time:", caplog.text, re.MULTILINE) + # assert re.search(r"p.time:", caplog.text, re.MULTILINE) # TODO From aed4f25cf59da8e6081452615fa754f990ad6844 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Tue, 3 Sep 2024 17:41:05 -0500 Subject: [PATCH 203/248] Reuse node to prevent overwriting channel settings to be sent out over the admin channel --- meshtastic/__main__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index e7886e6..f78155d 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -778,7 +778,8 @@ def onConnected(interface): channelIndex = mt_config.channel_index if channelIndex is None: meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1) - ch = interface.getNode(args.dest).channels[channelIndex] + node = interface.getNode(args.dest) + ch = node.channels[channelIndex] if args.ch_enable or args.ch_disable: print( @@ -836,7 +837,7 @@ def onConnected(interface): ch.role = channel_pb2.Channel.Role.DISABLED print(f"Writing modified channels to device") - interface.getNode(args.dest).writeChannel(channelIndex) + node.writeChannel(channelIndex) if args.get_canned_message: closeNow = True From 9612aea9b9518abc2e387157cbb548fdf8caee68 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Tue, 3 Sep 2024 21:47:07 -0500 Subject: [PATCH 204/248] Add in a retry mechanism for channel settings Attempts multiple times to fetch things over the admin channel before giving up. --- meshtastic/__main__.py | 6 ++++++ meshtastic/mesh_interface.py | 20 +++++++++++++++++--- meshtastic/node.py | 11 ++++++----- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index f78155d..ea9f6dd 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1423,6 +1423,12 @@ def initParser(): action="append", ) + group.add_argument( + "--channel-fetch-retries", + help=("Attempt to retrieve channel settings for --ch-set this many times before giving up."), + default=3, + ) + group.add_argument( "--ch-vlongslow", help="Change to the very long-range and slow channel", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index c59fcb3..b289668 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -314,7 +314,7 @@ class MeshInterface: # pylint: disable=R0902 return table def getNode( - self, nodeId: str, requestChannels: bool = True + self, nodeId: str, requestChannels: bool = True, requestChannelRetries: int = 3 ) -> meshtastic.node.Node: """Return a node object which contains device settings and channel info""" if nodeId in (LOCAL_ADDR, BROADCAST_ADDR): @@ -325,8 +325,22 @@ class MeshInterface: # pylint: disable=R0902 if requestChannels: logging.debug("About to requestChannels") n.requestChannels() - if not n.waitForConfig(): - our_exit("Error: Timed out waiting for channels") + retries_left = requestChannelRetries + last_index: int = 0 + while retries_left > 0: + retries_left -= 1 + if not n.waitForConfig(): + new_index: int = len(n.partialChannels) + # each time we get a new channel, reset the counter + if new_index != last_index: + retries_left = requestChannelRetries - 1 + if retries_left <= 0: + our_exit(f"Error: Timed out waiting for channels, giving up") + print("Timed out trying to retrieve channel info, retrying") + n.requestChannels(startingIndex=len(n.partialChannels)) + last_index = new_index + else: + break return n def sendText( diff --git a/meshtastic/node.py b/meshtastic/node.py index 48b9508..91c2d41 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -77,13 +77,14 @@ class Node: self.channels = channels self._fixupChannels() - def requestChannels(self): + def requestChannels(self, startingIndex: int = 0): """Send regular MeshPackets to ask channels.""" logging.debug(f"requestChannels for nodeNum:{self.nodeNum}") - self.channels = None - self.partialChannels = [] # We keep our channels in a temp array until finished - - self._requestChannel(0) + # only initialize if we're starting out fresh + if startingIndex == 0: + self.channels = None + self.partialChannels = [] # We keep our channels in a temp array until finished + self._requestChannel(startingIndex) def onResponseRequestSettings(self, p): """Handle the response packets for requesting settings _requestSettings()""" From b6547c97374368ca1837f4fa14a7b94403c60e29 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Tue, 3 Sep 2024 22:04:08 -0500 Subject: [PATCH 205/248] actually link up the retry args from the commandline to getNode --- meshtastic/__main__.py | 93 ++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index ea9f6dd..b43d595 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -273,6 +273,11 @@ def onConnected(interface): try: args = mt_config.args + # convenient place to store any keyword args we pass to getNode + getNode_kwargs = { + "requestChannelRetries": int(args.channel_fetch_retries) + } + # do not print this line if we are exporting the config if not args.export_config: print("Connected to radio") @@ -334,13 +339,13 @@ def onConnected(interface): closeNow = True waitForAckNak = True print(f"Setting device owner to {args.set_owner}") - interface.getNode(args.dest, False).setOwner(args.set_owner) + interface.getNode(args.dest, False, **getNode_kwargs).setOwner(args.set_owner) if args.set_owner_short: closeNow = True waitForAckNak = True print(f"Setting device owner short to {args.set_owner_short}") - interface.getNode(args.dest, False).setOwner( + interface.getNode(args.dest, False, **getNode_kwargs).setOwner( long_name=None, short_name=args.set_owner_short ) @@ -349,7 +354,7 @@ def onConnected(interface): closeNow = True waitForAckNak = True print(f"Setting canned plugin message to {args.set_canned_message}") - interface.getNode(args.dest, False).set_canned_message( + interface.getNode(args.dest, False, **getNode_kwargs).set_canned_message( args.set_canned_message ) @@ -358,12 +363,12 @@ def onConnected(interface): closeNow = True waitForAckNak = True print(f"Setting ringtone to {args.set_ringtone}") - interface.getNode(args.dest, False).set_ringtone(args.set_ringtone) + interface.getNode(args.dest, False, **getNode_kwargs).set_ringtone(args.set_ringtone) if args.pos_fields: # If --pos-fields invoked with args, set position fields closeNow = True - positionConfig = interface.getNode(args.dest).localConfig.position + positionConfig = interface.getNode(args.dest, **getNode_kwargs).localConfig.position allFields = 0 try: @@ -382,12 +387,12 @@ def onConnected(interface): print(f"Setting position fields to {allFields}") setPref(positionConfig, "position_flags", f"{allFields:d}") print("Writing modified preferences to device") - interface.getNode(args.dest).writeConfig("position") + interface.getNode(args.dest, **getNode_kwargs).writeConfig("position") elif args.pos_fields is not None: # If --pos-fields invoked without args, read and display current value closeNow = True - positionConfig = interface.getNode(args.dest).localConfig.position + positionConfig = interface.getNode(args.dest, **getNode_kwargs).localConfig.position fieldNames = [] for bit in positionConfig.PositionFlags.values(): @@ -398,56 +403,56 @@ def onConnected(interface): if args.set_ham: closeNow = True print(f"Setting Ham ID to {args.set_ham} and turning off encryption") - interface.getNode(args.dest).setOwner(args.set_ham, is_licensed=True) + interface.getNode(args.dest, **getNode_kwargs).setOwner(args.set_ham, is_licensed=True) # Must turn off encryption on primary channel - interface.getNode(args.dest).turnOffEncryptionOnPrimaryChannel() + interface.getNode(args.dest, **getNode_kwargs).turnOffEncryptionOnPrimaryChannel() if args.reboot: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).reboot() + interface.getNode(args.dest, False, **getNode_kwargs).reboot() if args.reboot_ota: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).rebootOTA() + interface.getNode(args.dest, False, **getNode_kwargs).rebootOTA() if args.enter_dfu: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).enterDFUMode() + interface.getNode(args.dest, False, **getNode_kwargs).enterDFUMode() if args.shutdown: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).shutdown() + interface.getNode(args.dest, False, **getNode_kwargs).shutdown() if args.device_metadata: closeNow = True - interface.getNode(args.dest, False).getMetadata() + interface.getNode(args.dest, False, **getNode_kwargs).getMetadata() if args.begin_edit: closeNow = True - interface.getNode(args.dest, False).beginSettingsTransaction() + interface.getNode(args.dest, False, **getNode_kwargs).beginSettingsTransaction() if args.commit_edit: closeNow = True - interface.getNode(args.dest, False).commitSettingsTransaction() + interface.getNode(args.dest, False, **getNode_kwargs).commitSettingsTransaction() if args.factory_reset: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).factoryReset() + interface.getNode(args.dest, False, **getNode_kwargs).factoryReset() if args.remove_node: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).removeNode(args.remove_node) + interface.getNode(args.dest, False, **getNode_kwargs).removeNode(args.remove_node) if args.reset_nodedb: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).resetNodeDb() + interface.getNode(args.dest, False, **getNode_kwargs).resetNodeDb() if args.sendtext: closeNow = True @@ -461,7 +466,7 @@ def onConnected(interface): args.dest, wantAck=True, channelIndex=channelIndex, - onResponse=interface.getNode(args.dest, False).onAckNak, + onResponse=interface.getNode(args.dest, False, **getNode_kwargs).onAckNak, ) else: meshtastic.util.our_exit( @@ -552,7 +557,7 @@ def onConnected(interface): if args.set: closeNow = True waitForAckNak = True - node = interface.getNode(args.dest, False) + node = interface.getNode(args.dest, False, **getNode_kwargs) # Handle the int/float/bool arguments pref = None @@ -591,19 +596,19 @@ def onConnected(interface): configuration = yaml.safe_load(file) closeNow = True - interface.getNode(args.dest, False).beginSettingsTransaction() + interface.getNode(args.dest, False, **getNode_kwargs).beginSettingsTransaction() if "owner" in configuration: print(f"Setting device owner to {configuration['owner']}") waitForAckNak = True - interface.getNode(args.dest, False).setOwner(configuration["owner"]) + interface.getNode(args.dest, False, **getNode_kwargs).setOwner(configuration["owner"]) if "owner_short" in configuration: print( f"Setting device owner short to {configuration['owner_short']}" ) waitForAckNak = True - interface.getNode(args.dest, False).setOwner( + interface.getNode(args.dest, False, **getNode_kwargs).setOwner( long_name=None, short_name=configuration["owner_short"] ) @@ -612,17 +617,17 @@ def onConnected(interface): f"Setting device owner short to {configuration['ownerShort']}" ) waitForAckNak = True - interface.getNode(args.dest, False).setOwner( + interface.getNode(args.dest, False, **getNode_kwargs).setOwner( long_name=None, short_name=configuration["ownerShort"] ) if "channel_url" in configuration: print("Setting channel url to", configuration["channel_url"]) - interface.getNode(args.dest).setURL(configuration["channel_url"]) + interface.getNode(args.dest, **getNode_kwargs).setURL(configuration["channel_url"]) if "channelUrl" in configuration: print("Setting channel url to", configuration["channelUrl"]) - interface.getNode(args.dest).setURL(configuration["channelUrl"]) + interface.getNode(args.dest, **getNode_kwargs).setURL(configuration["channelUrl"]) if "location" in configuration: alt = 0 @@ -647,28 +652,28 @@ def onConnected(interface): interface.localNode.writeConfig("position") if "config" in configuration: - localConfig = interface.getNode(args.dest).localConfig + localConfig = interface.getNode(args.dest, **getNode_kwargs).localConfig for section in configuration["config"]: traverseConfig( section, configuration["config"][section], localConfig ) - interface.getNode(args.dest).writeConfig( + interface.getNode(args.dest, **getNode_kwargs).writeConfig( meshtastic.util.camel_to_snake(section) ) if "module_config" in configuration: - moduleConfig = interface.getNode(args.dest).moduleConfig + moduleConfig = interface.getNode(args.dest, **getNode_kwargs).moduleConfig for section in configuration["module_config"]: traverseConfig( section, configuration["module_config"][section], moduleConfig, ) - interface.getNode(args.dest).writeConfig( + interface.getNode(args.dest, **getNode_kwargs).writeConfig( meshtastic.util.camel_to_snake(section) ) - interface.getNode(args.dest, False).commitSettingsTransaction() + interface.getNode(args.dest, False, **getNode_kwargs).commitSettingsTransaction() print("Writing modified configuration to device") if args.export_config: @@ -681,7 +686,7 @@ def onConnected(interface): if args.seturl: closeNow = True - interface.getNode(args.dest).setURL(args.seturl) + interface.getNode(args.dest, **getNode_kwargs).setURL(args.seturl) # handle changing channels @@ -697,7 +702,7 @@ def onConnected(interface): meshtastic.util.our_exit( "Warning: Channel name must be shorter. Channel not added." ) - n = interface.getNode(args.dest) + n = interface.getNode(args.dest, **getNode_kwargs) ch = n.getChannelByName(args.ch_add) if ch: meshtastic.util.our_exit( @@ -736,7 +741,7 @@ def onConnected(interface): ) else: print(f"Deleting channel {channelIndex}") - ch = interface.getNode(args.dest).deleteChannel(channelIndex) + ch = interface.getNode(args.dest, **getNode_kwargs).deleteChannel(channelIndex) def setSimpleConfig(modem_preset): """Set one of the simple modem_config""" @@ -746,9 +751,9 @@ def onConnected(interface): "Warning: Cannot set modem preset for non-primary channel", 1 ) # Overwrite modem_preset - prefs = interface.getNode(args.dest).localConfig + prefs = interface.getNode(args.dest, **getNode_kwargs).localConfig prefs.lora.modem_preset = modem_preset - interface.getNode(args.dest).writeConfig("lora") + interface.getNode(args.dest, **getNode_kwargs).writeConfig("lora") # handle the simple radio set commands if args.ch_vlongslow: @@ -778,7 +783,7 @@ def onConnected(interface): channelIndex = mt_config.channel_index if channelIndex is None: meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1) - node = interface.getNode(args.dest) + node = interface.getNode(args.dest, **getNode_kwargs) ch = node.channels[channelIndex] if args.ch_enable or args.ch_disable: @@ -842,12 +847,12 @@ def onConnected(interface): if args.get_canned_message: closeNow = True print("") - interface.getNode(args.dest).get_canned_message() + interface.getNode(args.dest, **getNode_kwargs).get_canned_message() if args.get_ringtone: closeNow = True print("") - interface.getNode(args.dest).get_ringtone() + interface.getNode(args.dest, **getNode_kwargs).get_ringtone() if args.info: print("") @@ -855,7 +860,7 @@ def onConnected(interface): if args.dest == BROADCAST_ADDR: interface.showInfo() print("") - interface.getNode(args.dest).showInfo() + interface.getNode(args.dest, **getNode_kwargs).showInfo() closeNow = True print("") pypi_version = meshtastic.util.check_if_newer_version() @@ -872,7 +877,7 @@ def onConnected(interface): if args.get: closeNow = True - node = interface.getNode(args.dest, False) + node = interface.getNode(args.dest, False, **getNode_kwargs) for pref in args.get: found = getPref(node, pref[0]) @@ -888,7 +893,7 @@ def onConnected(interface): if args.qr or args.qr_all: closeNow = True - url = interface.getNode(args.dest, True).getURL(includeAll=args.qr_all) + url = interface.getNode(args.dest, True, **getNode_kwargs).getURL(includeAll=args.qr_all) if args.qr_all: urldesc = "Complete URL (includes all channels)" else: @@ -943,7 +948,7 @@ def onConnected(interface): print( f"Waiting for an acknowledgment from remote node (this could take a while)" ) - interface.getNode(args.dest, False).iface.waitForAckNak() + interface.getNode(args.dest, False, **getNode_kwargs).iface.waitForAckNak() if args.wait_to_disconnect: print(f"Waiting {args.wait_to_disconnect} seconds before disconnecting") From 3811226a61815fdb3576d64d9c1ae7433e0151c5 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Tue, 3 Sep 2024 22:12:03 -0500 Subject: [PATCH 206/248] add a configurable timeout --- meshtastic/__main__.py | 9 ++++++++- meshtastic/mesh_interface.py | 4 ++-- meshtastic/node.py | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index b43d595..fcfb385 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -275,7 +275,8 @@ def onConnected(interface): # convenient place to store any keyword args we pass to getNode getNode_kwargs = { - "requestChannelRetries": int(args.channel_fetch_retries) + "requestChannelRetries": int(args.channel_fetch_retries), + "timeout": int(args.timeout) } # do not print this line if we are exporting the config @@ -1434,6 +1435,12 @@ def initParser(): default=3, ) + group.add_argument( + "--timeout", + help="How long to wait for replies", + default=300 + ) + group.add_argument( "--ch-vlongslow", help="Change to the very long-range and slow channel", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index b289668..48fff56 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -314,13 +314,13 @@ class MeshInterface: # pylint: disable=R0902 return table def getNode( - self, nodeId: str, requestChannels: bool = True, requestChannelRetries: int = 3 + self, nodeId: str, requestChannels: bool = True, requestChannelRetries: int = 3, timeout: int = 300 ) -> meshtastic.node.Node: """Return a node object which contains device settings and channel info""" if nodeId in (LOCAL_ADDR, BROADCAST_ADDR): return self.localNode else: - n = meshtastic.node.Node(self, nodeId) + n = meshtastic.node.Node(self, nodeId, timeout=timeout) # Only request device settings and channel info when necessary if requestChannels: logging.debug("About to requestChannels") diff --git a/meshtastic/node.py b/meshtastic/node.py index 91c2d41..964e680 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -25,14 +25,14 @@ class Node: Includes methods for localConfig, moduleConfig and channels """ - def __init__(self, iface, nodeNum, noProto=False): + def __init__(self, iface, nodeNum, noProto=False, timeout: int = 300): """Constructor""" self.iface = iface self.nodeNum = nodeNum self.localConfig = localonly_pb2.LocalConfig() self.moduleConfig = localonly_pb2.LocalModuleConfig() self.channels = None - self._timeout = Timeout(maxSecs=300) + self._timeout = Timeout(maxSecs=timeout) self.partialChannels = None self.noProto = noProto self.cannedPluginMessage = None From a689fd73a29271e00d93641f853c561b9aa787a1 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 5 Sep 2024 13:49:28 -0700 Subject: [PATCH 207/248] Deprecate --no-time and remove behavior, followup to #663 --- meshtastic/__main__.py | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index f78155d..a8e1547 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -314,21 +314,6 @@ def onConnected(interface): print("Setting device position and enabling fixed position setting") # can include lat/long/alt etc: latitude = 37.5, longitude = -122.1 interface.localNode.setFixedPosition(lat, lon, alt) - elif not args.no_time: - # We normally provide a current time to the mesh when we connect - if ( - interface.localNode.nodeNum in interface.nodesByNum - and "position" in interface.nodesByNum[interface.localNode.nodeNum] - ): - # send the same position the node already knows, just to update time - position = interface.nodesByNum[interface.localNode.nodeNum]["position"] - interface.sendPosition( - position.get("latitude", 0.0), - position.get("longitude", 0.0), - position.get("altitude", 0.0), - ) - else: - interface.sendPosition() if args.set_owner: closeNow = True @@ -1588,7 +1573,7 @@ def initParser(): group.add_argument( "--no-time", - help="Suppress sending the current time to the mesh", + help="Deprecated. Retained for backwards compatibility in scripts, but is a no-op.", action="store_true", ) From 17f36057365751d23db46557b4eb203e639d5734 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 5 Sep 2024 13:58:02 -0700 Subject: [PATCH 208/248] Ensure set-owner combined with set-owner-short sets both values --- meshtastic/__main__.py | 27 ++++++++++++--------------- meshtastic/node.py | 4 ++-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index a8e1547..3184d2a 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -315,19 +315,16 @@ def onConnected(interface): # can include lat/long/alt etc: latitude = 37.5, longitude = -122.1 interface.localNode.setFixedPosition(lat, lon, alt) - if args.set_owner: + if args.set_owner or args.set_owner_short: closeNow = True waitForAckNak = True - print(f"Setting device owner to {args.set_owner}") - interface.getNode(args.dest, False).setOwner(args.set_owner) - - if args.set_owner_short: - closeNow = True - waitForAckNak = True - print(f"Setting device owner short to {args.set_owner_short}") - interface.getNode(args.dest, False).setOwner( - long_name=None, short_name=args.set_owner_short - ) + 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).setOwner(long_name=args.set_owner, short_name=args.set_owner_short) # TODO: add to export-config and configure if args.set_canned_message: @@ -1452,6 +1449,10 @@ def initParser(): group.add_argument("--set-owner", help="Set device owner name", action="store") + group.add_argument( + "--set-owner-short", help="Set device owner short name", action="store" + ) + group.add_argument( "--set-canned-message", help="Set the canned messages plugin message (up to 200 characters).", @@ -1464,10 +1465,6 @@ def initParser(): action="store", ) - group.add_argument( - "--set-owner-short", help="Set device owner short name", action="store" - ) - group.add_argument( "--set-ham", help="Set licensed Ham ID and turn off encryption", action="store" ) diff --git a/meshtastic/node.py b/meshtastic/node.py index 48b9508..5f5ed7d 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -5,7 +5,7 @@ import base64 import logging import time -from typing import Union +from typing import Optional, Union from meshtastic.protobuf import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2 from meshtastic.util import ( @@ -279,7 +279,7 @@ class Node: return c.index return 0 - def setOwner(self, long_name=None, short_name=None, is_licensed=False): + def setOwner(self, long_name: Optional[str]=None, short_name: Optional[str]=None, is_licensed: bool=False): """Set device owner name""" logging.debug(f"in setOwner nodeNum:{self.nodeNum}") p = admin_pb2.AdminMessage() From 23bb2e26f96e1a383237657516601b760d80a629 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 5 Sep 2024 21:22:03 +0000 Subject: [PATCH 209/248] bump version to 2.4.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1767bda..50ecdd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.1a0" +version = "2.4.1" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 0813e8dba65d04026d81751a8841acb04a1a542d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 5 Sep 2024 14:27:38 -0700 Subject: [PATCH 210/248] protobufs: v2.4.2; bump to alpha version --- meshtastic/protobuf/mesh_pb2.py | 4 ++-- meshtastic/protobuf/mesh_pb2.pyi | 22 ++++++++++++++++++++++ protobufs | 2 +- pyproject.toml | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 6016cdd..32f4706 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xd0\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xee\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x42_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xd0\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -36,7 +36,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_CONSTANTS']._serialized_start=6906 _globals['_CONSTANTS']._serialized_end=6950 _globals['_CRITICALERRORCODE']._serialized_start=6953 - _globals['_CRITICALERRORCODE']._serialized_end=7191 + _globals['_CRITICALERRORCODE']._serialized_end=7261 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 2e53c48..2e56b48 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -747,6 +747,17 @@ class _CriticalErrorCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapp A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug """ + FLASH_CORRUPTION_RECOVERABLE: _CriticalErrorCode.ValueType # 12 + """ + Corruption was detected on the flash filesystem but we were able to repair things. + If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. + """ + FLASH_CORRUPTION_UNRECOVERABLE: _CriticalErrorCode.ValueType # 13 + """ + Corruption was detected on the flash filesystem but we were unable to repair things. + NOTE: Your node will probably need to be reconfigured the next time it reboots (it will lose the region code etc...) + If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. + """ class CriticalErrorCode(_CriticalErrorCode, metaclass=_CriticalErrorCodeEnumTypeWrapper): """ @@ -805,6 +816,17 @@ RADIO_SPI_BUG: CriticalErrorCode.ValueType # 11 A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug """ +FLASH_CORRUPTION_RECOVERABLE: CriticalErrorCode.ValueType # 12 +""" +Corruption was detected on the flash filesystem but we were able to repair things. +If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. +""" +FLASH_CORRUPTION_UNRECOVERABLE: CriticalErrorCode.ValueType # 13 +""" +Corruption was detected on the flash filesystem but we were unable to repair things. +NOTE: Your node will probably need to be reconfigured the next time it reboots (it will lose the region code etc...) +If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field. +""" global___CriticalErrorCode = CriticalErrorCode @typing.final diff --git a/protobufs b/protobufs index b1a79d5..d0fe91a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b1a79d5db00f6aeeb0bbae156e8939e146c95299 +Subproject commit d0fe91ab99734cacdc188403f73fe30f766917cf diff --git a/pyproject.toml b/pyproject.toml index 50ecdd2..538cb64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.1" +version = "2.4.2a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 78d8403bbdd8bc7bddee3fc1031d9e22aa6a5dfa Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Fri, 6 Sep 2024 00:08:20 -0700 Subject: [PATCH 211/248] Update telemetry in interface.nodes on receiving device metrics packets --- meshtastic/__init__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index f4d91fd..1c71795 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -191,6 +191,16 @@ def _onNodeInfoReceive(iface, asDict): iface.nodes[p["id"]] = n _receiveInfoUpdate(iface, asDict) +def _onTelemetryReceive(iface, asDict): + """Automatically update device metrics on received packets""" + logging.debug(f"in _onTelemetryReceive() asDict:{asDict}") + deviceMetrics = asDict.get("decoded", {}).get("telemetry", {}).get("deviceMetrics") + if "from" in asDict and deviceMetrics is not None: + node = iface._getOrCreateByNum(asDict["from"]) + newMetrics = node.get("deviceMetrics", {}) + newMetrics.update(deviceMetrics) + logging.debug(f"updating metrics for {asDict['from']} to {newMetrics}") + node["deviceMetrics"] = newMetrics def _receiveInfoUpdate(iface, asDict): if "from" in asDict: @@ -221,7 +231,7 @@ protocols = { portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage), portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing), portnums_pb2.PortNum.TELEMETRY_APP: KnownProtocol( - "telemetry", telemetry_pb2.Telemetry + "telemetry", telemetry_pb2.Telemetry, _onTelemetryReceive ), portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol( "remotehw", remote_hardware_pb2.HardwareMessage From 0d26c26f7e153dcfe7ba91564053c8cb902037b9 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Fri, 6 Sep 2024 23:13:31 -0700 Subject: [PATCH 212/248] update protobufs to master --- meshtastic/protobuf/config_pb2.py | 98 +++++++++++------------ meshtastic/protobuf/config_pb2.pyi | 49 +++++------- meshtastic/protobuf/mesh_pb2.py | 108 +++++++++++++------------- meshtastic/protobuf/mesh_pb2.pyi | 52 ++++++++++++- meshtastic/protobuf/telemetry_pb2.py | 4 +- meshtastic/protobuf/telemetry_pb2.pyi | 8 ++ protobufs | 2 +- 7 files changed, 181 insertions(+), 140 deletions(-) diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index ef92476..94af1a3 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xf5&\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x1a\xb3\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x1d\n\x11\x64\x65\x62ug_log_enabled\x18\x03 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xf0\x06\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\xa9\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x1a\xda\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\x12\"\n\x16\x64\x65vice_logging_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xd9\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x01(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12!\n\x19\x62luetooth_logging_enabled\x18\x07 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\"\xaa&\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x1a\x94\x05\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\"\xae\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x0c\n\x08REPEATER\x10\x04\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\"Q\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x90\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\x1a\xfa\x07\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12Q\n\ngps_format\x18\x02 \x01(\x0e\x32=.meshtastic.protobuf.Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x19\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\"M\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\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"M\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x8b\x07\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\x12\x19\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\"\xcd\x01\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\"\xa9\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\r\n\tLONG_SLOW\x10\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xb6\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x03(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBa\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -25,8 +25,6 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._serialized_options = b'\010\001' _CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._options = None _CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._serialized_options = b'\030\001' - _CONFIG_DEVICECONFIG.fields_by_name['debug_log_enabled']._options = None - _CONFIG_DEVICECONFIG.fields_by_name['debug_log_enabled']._serialized_options = b'\030\001' _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._options = None _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._serialized_options = b'\030\001' _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None @@ -35,54 +33,52 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._options = None _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001' - _CONFIG_BLUETOOTHCONFIG.fields_by_name['device_logging_enabled']._options = None - _CONFIG_BLUETOOTHCONFIG.fields_by_name['device_logging_enabled']._serialized_options = b'\030\001' _globals['_CONFIG']._serialized_start=58 - _globals['_CONFIG']._serialized_end=5039 + _globals['_CONFIG']._serialized_end=4964 _globals['_CONFIG_DEVICECONFIG']._serialized_start=629 - _globals['_CONFIG_DEVICECONFIG']._serialized_end=1320 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1063 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1237 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1239 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1320 - _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1323 - _globals['_CONFIG_POSITIONCONFIG']._serialized_end=1989 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=1763 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=1934 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1936 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1989 - _globals['_CONFIG_POWERCONFIG']._serialized_start=1992 - _globals['_CONFIG_POWERCONFIG']._serialized_end=2252 - _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2255 - _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2655 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2548 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2618 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2620 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2655 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2658 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3676 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3222 - _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3299 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3301 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3341 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3343 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3420 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3422 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3487 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3490 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3676 - _globals['_CONFIG_LORACONFIG']._serialized_start=3679 - _globals['_CONFIG_LORACONFIG']._serialized_end=4559 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4182 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4387 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4390 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4559 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4562 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4780 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4724 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4780 - _globals['_CONFIG_SECURITYCONFIG']._serialized_start=4783 - _globals['_CONFIG_SECURITYCONFIG']._serialized_end=5000 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=5002 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=5020 + _globals['_CONFIG_DEVICECONFIG']._serialized_end=1289 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1032 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1206 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1208 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1289 + _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1292 + _globals['_CONFIG_POSITIONCONFIG']._serialized_end=1958 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=1732 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=1903 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=1905 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=1958 + _globals['_CONFIG_POWERCONFIG']._serialized_start=1961 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2221 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2224 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=2624 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2517 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2587 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2589 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=2624 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=2627 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=3645 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_start=3191 + _globals['_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT']._serialized_end=3268 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3270 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3310 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3312 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3389 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3391 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3456 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3459 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=3645 + _globals['_CONFIG_LORACONFIG']._serialized_start=3648 + _globals['_CONFIG_LORACONFIG']._serialized_end=4555 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4178 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4383 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4386 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=4555 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=4558 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=4740 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=4684 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=4740 + _globals['_CONFIG_SECURITYCONFIG']._serialized_start=4743 + _globals['_CONFIG_SECURITYCONFIG']._serialized_end=4925 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=4927 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=4945 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 0b32e91..2964272 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -239,7 +239,6 @@ class Config(google.protobuf.message.Message): ROLE_FIELD_NUMBER: builtins.int SERIAL_ENABLED_FIELD_NUMBER: builtins.int - DEBUG_LOG_ENABLED_FIELD_NUMBER: builtins.int BUTTON_GPIO_FIELD_NUMBER: builtins.int BUZZER_GPIO_FIELD_NUMBER: builtins.int REBROADCAST_MODE_FIELD_NUMBER: builtins.int @@ -258,12 +257,6 @@ class Config(google.protobuf.message.Message): Disabling this will disable the SerialConsole by not initilizing the StreamAPI Moved to SecurityConfig """ - debug_log_enabled: builtins.bool - """ - By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). - Set this to true to leave the debug log outputting even when API is active. - Moved to SecurityConfig - """ button_gpio: builtins.int """ For boards without a hard wired button, this is the pin number that will be used @@ -310,7 +303,6 @@ class Config(google.protobuf.message.Message): *, role: global___Config.DeviceConfig.Role.ValueType = ..., serial_enabled: builtins.bool = ..., - debug_log_enabled: builtins.bool = ..., button_gpio: builtins.int = ..., buzzer_gpio: builtins.int = ..., rebroadcast_mode: global___Config.DeviceConfig.RebroadcastMode.ValueType = ..., @@ -321,7 +313,7 @@ class Config(google.protobuf.message.Message): tzdef: builtins.str = ..., led_heartbeat_disabled: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["button_gpio", b"button_gpio", "buzzer_gpio", b"buzzer_gpio", "debug_log_enabled", b"debug_log_enabled", "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): @@ -1398,6 +1390,7 @@ class Config(google.protobuf.message.Message): PA_FAN_DISABLED_FIELD_NUMBER: builtins.int IGNORE_INCOMING_FIELD_NUMBER: builtins.int IGNORE_MQTT_FIELD_NUMBER: builtins.int + CONFIG_OK_TO_MQTT_FIELD_NUMBER: builtins.int use_preset: builtins.bool """ When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` @@ -1491,6 +1484,10 @@ class Config(google.protobuf.message.Message): """ If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. """ + config_ok_to_mqtt: builtins.bool + """ + Sets the ok_to_mqtt bit on outgoing packets + """ @property def ignore_incoming(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: """ @@ -1519,8 +1516,9 @@ class Config(google.protobuf.message.Message): pa_fan_disabled: builtins.bool = ..., ignore_incoming: collections.abc.Iterable[builtins.int] | None = ..., ignore_mqtt: builtins.bool = ..., + config_ok_to_mqtt: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "pa_fan_disabled", b"pa_fan_disabled", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... + def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "config_ok_to_mqtt", b"config_ok_to_mqtt", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "pa_fan_disabled", b"pa_fan_disabled", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... @typing.final class BluetoothConfig(google.protobuf.message.Message): @@ -1562,7 +1560,6 @@ class Config(google.protobuf.message.Message): ENABLED_FIELD_NUMBER: builtins.int MODE_FIELD_NUMBER: builtins.int FIXED_PIN_FIELD_NUMBER: builtins.int - DEVICE_LOGGING_ENABLED_FIELD_NUMBER: builtins.int enabled: builtins.bool """ Enable Bluetooth on the device @@ -1575,20 +1572,14 @@ class Config(google.protobuf.message.Message): """ Specified PIN for PairingMode.FixedPin """ - device_logging_enabled: builtins.bool - """ - Enables device (serial style logs) over Bluetooth - Moved to SecurityConfig - """ def __init__( self, *, enabled: builtins.bool = ..., mode: global___Config.BluetoothConfig.PairingMode.ValueType = ..., fixed_pin: builtins.int = ..., - device_logging_enabled: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["device_logging_enabled", b"device_logging_enabled", "enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... + def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "fixed_pin", b"fixed_pin", "mode", b"mode"]) -> None: ... @typing.final class SecurityConfig(google.protobuf.message.Message): @@ -1600,7 +1591,6 @@ class Config(google.protobuf.message.Message): IS_MANAGED_FIELD_NUMBER: builtins.int SERIAL_ENABLED_FIELD_NUMBER: builtins.int DEBUG_LOG_API_ENABLED_FIELD_NUMBER: builtins.int - BLUETOOTH_LOGGING_ENABLED_FIELD_NUMBER: builtins.int ADMIN_CHANNEL_ENABLED_FIELD_NUMBER: builtins.int public_key: builtins.bytes """ @@ -1612,10 +1602,6 @@ class Config(google.protobuf.message.Message): The private key of the device. Used to create a shared key with a remote device. """ - admin_key: builtins.bytes - """ - The public key authorized to send admin messages to this node. - """ is_managed: builtins.bool """ If true, device is considered to be "managed" by a mesh administrator via admin messages @@ -1628,29 +1614,30 @@ class Config(google.protobuf.message.Message): debug_log_api_enabled: builtins.bool """ By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). - Output live debug logging over serial. - """ - bluetooth_logging_enabled: builtins.bool - """ - Enables device (serial style logs) over Bluetooth + Output live debug logging over serial or bluetooth is set to true. """ admin_channel_enabled: builtins.bool """ Allow incoming device control over the insecure legacy admin channel. """ + @property + def admin_key(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bytes]: + """ + The public key authorized to send admin messages to this node. + """ + def __init__( self, *, public_key: builtins.bytes = ..., private_key: builtins.bytes = ..., - admin_key: builtins.bytes = ..., + admin_key: collections.abc.Iterable[builtins.bytes] | None = ..., is_managed: builtins.bool = ..., serial_enabled: builtins.bool = ..., debug_log_api_enabled: builtins.bool = ..., - bluetooth_logging_enabled: builtins.bool = ..., admin_channel_enabled: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["admin_channel_enabled", b"admin_channel_enabled", "admin_key", b"admin_key", "bluetooth_logging_enabled", b"bluetooth_logging_enabled", "debug_log_api_enabled", b"debug_log_api_enabled", "is_managed", b"is_managed", "private_key", b"private_key", "public_key", b"public_key", "serial_enabled", b"serial_enabled"]) -> None: ... + def ClearField(self, field_name: typing.Literal["admin_channel_enabled", b"admin_channel_enabled", "admin_key", b"admin_key", "debug_log_api_enabled", b"debug_log_api_enabled", "is_managed", b"is_managed", "private_key", b"private_key", "public_key", b"public_key", "serial_enabled", b"serial_enabled"]) -> None: ... @typing.final class SessionkeyConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 425fbfa..9251717 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xbf\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xf2\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xdb\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x9a\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xbf\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xf2\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xf3\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"s\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xde\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,12 +31,12 @@ if _descriptor._USE_C_DESCRIPTORS == False: _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _globals['_HARDWAREMODEL']._serialized_start=6123 - _globals['_HARDWAREMODEL']._serialized_end=7557 - _globals['_CONSTANTS']._serialized_start=7559 - _globals['_CONSTANTS']._serialized_end=7603 - _globals['_CRITICALERRORCODE']._serialized_start=7606 - _globals['_CRITICALERRORCODE']._serialized_end=7914 + _globals['_HARDWAREMODEL']._serialized_start=6183 + _globals['_HARDWAREMODEL']._serialized_end=7685 + _globals['_CONSTANTS']._serialized_start=7687 + _globals['_CONSTANTS']._serialized_end=7731 + _globals['_CRITICALERRORCODE']._serialized_start=7734 + _globals['_CRITICALERRORCODE']._serialized_end=8042 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1194 _globals['_POSITION_LOCSOURCE']._serialized_start=889 @@ -52,51 +52,51 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_ROUTING_ERROR']._serialized_start=1720 _globals['_ROUTING_ERROR']._serialized_end=1962 _globals['_DATA']._serialized_start=1976 - _globals['_DATA']._serialized_end=2152 - _globals['_WAYPOINT']._serialized_start=2155 - _globals['_WAYPOINT']._serialized_end=2343 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2345 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2453 - _globals['_MESHPACKET']._serialized_start=2456 - _globals['_MESHPACKET']._serialized_end=3059 - _globals['_MESHPACKET_PRIORITY']._serialized_start=2881 - _globals['_MESHPACKET_PRIORITY']._serialized_end=2972 - _globals['_MESHPACKET_DELAYED']._serialized_start=2974 - _globals['_MESHPACKET_DELAYED']._serialized_end=3040 - _globals['_NODEINFO']._serialized_start=3062 - _globals['_NODEINFO']._serialized_end=3343 - _globals['_MYNODEINFO']._serialized_start=3345 - _globals['_MYNODEINFO']._serialized_end=3425 - _globals['_LOGRECORD']._serialized_start=3428 - _globals['_LOGRECORD']._serialized_end=3629 - _globals['_LOGRECORD_LEVEL']._serialized_start=3541 - _globals['_LOGRECORD_LEVEL']._serialized_end=3629 - _globals['_QUEUESTATUS']._serialized_start=3631 - _globals['_QUEUESTATUS']._serialized_end=3711 - _globals['_FROMRADIO']._serialized_start=3714 - _globals['_FROMRADIO']._serialized_end=4538 - _globals['_CLIENTNOTIFICATION']._serialized_start=4541 - _globals['_CLIENTNOTIFICATION']._serialized_end=4681 - _globals['_FILEINFO']._serialized_start=4683 - _globals['_FILEINFO']._serialized_end=4732 - _globals['_TORADIO']._serialized_start=4735 - _globals['_TORADIO']._serialized_end=5047 - _globals['_COMPRESSED']._serialized_start=5049 - _globals['_COMPRESSED']._serialized_end=5122 - _globals['_NEIGHBORINFO']._serialized_start=5125 - _globals['_NEIGHBORINFO']._serialized_end=5269 - _globals['_NEIGHBOR']._serialized_start=5271 - _globals['_NEIGHBOR']._serialized_end=5371 - _globals['_DEVICEMETADATA']._serialized_start=5374 - _globals['_DEVICEMETADATA']._serialized_end=5693 - _globals['_HEARTBEAT']._serialized_start=5695 - _globals['_HEARTBEAT']._serialized_end=5706 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5708 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5802 - _globals['_CHUNKEDPAYLOAD']._serialized_start=5804 - _globals['_CHUNKEDPAYLOAD']._serialized_end=5905 - _globals['_RESEND_CHUNKS']._serialized_start=5907 - _globals['_RESEND_CHUNKS']._serialized_end=5938 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=5941 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=6120 + _globals['_DATA']._serialized_end=2188 + _globals['_WAYPOINT']._serialized_start=2191 + _globals['_WAYPOINT']._serialized_end=2379 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2381 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2489 + _globals['_MESHPACKET']._serialized_start=2492 + _globals['_MESHPACKET']._serialized_end=3119 + _globals['_MESHPACKET_PRIORITY']._serialized_start=2917 + _globals['_MESHPACKET_PRIORITY']._serialized_end=3032 + _globals['_MESHPACKET_DELAYED']._serialized_start=3034 + _globals['_MESHPACKET_DELAYED']._serialized_end=3100 + _globals['_NODEINFO']._serialized_start=3122 + _globals['_NODEINFO']._serialized_end=3403 + _globals['_MYNODEINFO']._serialized_start=3405 + _globals['_MYNODEINFO']._serialized_end=3485 + _globals['_LOGRECORD']._serialized_start=3488 + _globals['_LOGRECORD']._serialized_end=3689 + _globals['_LOGRECORD_LEVEL']._serialized_start=3601 + _globals['_LOGRECORD_LEVEL']._serialized_end=3689 + _globals['_QUEUESTATUS']._serialized_start=3691 + _globals['_QUEUESTATUS']._serialized_end=3771 + _globals['_FROMRADIO']._serialized_start=3774 + _globals['_FROMRADIO']._serialized_end=4598 + _globals['_CLIENTNOTIFICATION']._serialized_start=4601 + _globals['_CLIENTNOTIFICATION']._serialized_end=4741 + _globals['_FILEINFO']._serialized_start=4743 + _globals['_FILEINFO']._serialized_end=4792 + _globals['_TORADIO']._serialized_start=4795 + _globals['_TORADIO']._serialized_end=5107 + _globals['_COMPRESSED']._serialized_start=5109 + _globals['_COMPRESSED']._serialized_end=5182 + _globals['_NEIGHBORINFO']._serialized_start=5185 + _globals['_NEIGHBORINFO']._serialized_end=5329 + _globals['_NEIGHBOR']._serialized_start=5331 + _globals['_NEIGHBOR']._serialized_end=5431 + _globals['_DEVICEMETADATA']._serialized_start=5434 + _globals['_DEVICEMETADATA']._serialized_end=5753 + _globals['_HEARTBEAT']._serialized_start=5755 + _globals['_HEARTBEAT']._serialized_end=5766 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5768 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5862 + _globals['_CHUNKEDPAYLOAD']._serialized_start=5864 + _globals['_CHUNKEDPAYLOAD']._serialized_end=5965 + _globals['_RESEND_CHUNKS']._serialized_start=5967 + _globals['_RESEND_CHUNKS']._serialized_end=5998 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=6001 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=6180 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 570fe2e..15c8680 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -349,6 +349,18 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ Minewsemi ME25LS01 (ME25LE01_V1.0). NRF52840 w/ LR1110 radio, buttons and leds and pins. """ + RP2040_FEATHER_RFM95: _HardwareModel.ValueType # 76 + """ + RP2040_FEATHER_RFM95 + Adafruit Feather RP2040 with RFM95 LoRa Radio RFM95 with SX1272, SSD1306 OLED + https://www.adafruit.com/product/5714 + https://www.adafruit.com/product/326 + https://www.adafruit.com/product/938 + ^^^ short A0 to switch to I2C address 0x3C + """ + M5STACK_COREBASIC: _HardwareModel.ValueType # 77 + """M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/""" + M5STACK_CORE2: _HardwareModel.ValueType # 78 PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -682,6 +694,18 @@ ME25LS01_4Y10TD: HardwareModel.ValueType # 75 """ Minewsemi ME25LS01 (ME25LE01_V1.0). NRF52840 w/ LR1110 radio, buttons and leds and pins. """ +RP2040_FEATHER_RFM95: HardwareModel.ValueType # 76 +""" +RP2040_FEATHER_RFM95 +Adafruit Feather RP2040 with RFM95 LoRa Radio RFM95 with SX1272, SSD1306 OLED +https://www.adafruit.com/product/5714 +https://www.adafruit.com/product/326 +https://www.adafruit.com/product/938 + ^^^ short A0 to switch to I2C address 0x3C +""" +M5STACK_COREBASIC: HardwareModel.ValueType # 77 +"""M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/""" +M5STACK_CORE2: HardwareModel.ValueType # 78 PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -1482,6 +1506,7 @@ class Data(google.protobuf.message.Message): REQUEST_ID_FIELD_NUMBER: builtins.int REPLY_ID_FIELD_NUMBER: builtins.int EMOJI_FIELD_NUMBER: builtins.int + BITFIELD_FIELD_NUMBER: builtins.int portnum: meshtastic.protobuf.portnums_pb2.PortNum.ValueType """ Formerly named typ and of type Type @@ -1524,6 +1549,10 @@ class Data(google.protobuf.message.Message): Defaults to false. If true, then what is in the payload should be treated as an emoji like giving a message a heart or poop emoji. """ + bitfield: builtins.int + """ + Bitfield for extra flags. First use is to indicate that user approves the packet being uploaded to MQTT. + """ def __init__( self, *, @@ -1535,8 +1564,11 @@ class Data(google.protobuf.message.Message): request_id: builtins.int = ..., reply_id: builtins.int = ..., emoji: builtins.int = ..., + bitfield: builtins.int | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["dest", b"dest", "emoji", b"emoji", "payload", b"payload", "portnum", b"portnum", "reply_id", b"reply_id", "request_id", b"request_id", "source", b"source", "want_response", b"want_response"]) -> None: ... + def HasField(self, field_name: typing.Literal["_bitfield", b"_bitfield", "bitfield", b"bitfield"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_bitfield", b"_bitfield", "bitfield", b"bitfield", "dest", b"dest", "emoji", b"emoji", "payload", b"payload", "portnum", b"portnum", "reply_id", b"reply_id", "request_id", b"request_id", "source", b"source", "want_response", b"want_response"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_bitfield", b"_bitfield"]) -> typing.Literal["bitfield"] | None: ... global___Data = Data @@ -1690,6 +1722,15 @@ class MeshPacket(google.protobuf.message.Message): If priority is unset but the message is marked as want_ack, assume it is important and use a slightly higher priority """ + RESPONSE: MeshPacket._Priority.ValueType # 80 + """ + If priority is unset but the packet is a response to a request, we want it to get there relatively quickly. + Furthermore, responses stop relaying packets directed to a node early. + """ + HIGH: MeshPacket._Priority.ValueType # 100 + """ + Higher priority for specific message types (portnums) to distinguish between other reliable packets. + """ ACK: MeshPacket._Priority.ValueType # 120 """ Ack/naks are sent with very high priority to ensure that retransmission @@ -1744,6 +1785,15 @@ class MeshPacket(google.protobuf.message.Message): If priority is unset but the message is marked as want_ack, assume it is important and use a slightly higher priority """ + RESPONSE: MeshPacket.Priority.ValueType # 80 + """ + If priority is unset but the packet is a response to a request, we want it to get there relatively quickly. + Furthermore, responses stop relaying packets directed to a node early. + """ + HIGH: MeshPacket.Priority.ValueType # 100 + """ + Higher priority for specific message types (portnums) to distinguish between other reliable packets. + """ ACK: MeshPacket.Priority.ValueType # 120 """ Ack/naks are sent with very high priority to ensure that retransmission diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 3039500..5b2c5bc 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa4\x05\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lull\"\x8a\x02\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_current\"\xeb\x04\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100um\"\xd5\x01\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\"\xe5\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\x92\x03\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa4\x05\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lull\"\x8a\x02\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_current\"\xeb\x04\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100um\"\xd5\x01\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\"\xe5\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xa5\x03\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -22,7 +22,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_TELEMETRYSENSORTYPE']._serialized_start=2517 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=2919 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=2938 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=304 _globals['_ENVIRONMENTMETRICS']._serialized_start=307 diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index f528fcd..98b292f 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -139,6 +139,10 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) """ + CUSTOM_SENSOR: _TelemetrySensorType.ValueType # 29 + """ + Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -261,6 +265,10 @@ MAX17048: TelemetrySensorType.ValueType # 28 """ MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) """ +CUSTOM_SENSOR: TelemetrySensorType.ValueType # 29 +""" +Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor +""" global___TelemetrySensorType = TelemetrySensorType @typing.final diff --git a/protobufs b/protobufs index b15c081..0acaec6 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b15c081cb314c7407205ebe98b0f6d4345ae80bd +Subproject commit 0acaec6eff00e748beeae89148093221f131cd9c From 8ba92da7cf4257a25dc0fb4e6f4d2212f146ab5e Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Fri, 6 Sep 2024 23:38:52 -0700 Subject: [PATCH 213/248] Change modem preset shortcuts to not request channels, and to request remote config when needed --- meshtastic/__main__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3184d2a..33ac339 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -728,9 +728,11 @@ def onConnected(interface): "Warning: Cannot set modem preset for non-primary channel", 1 ) # Overwrite modem_preset - prefs = interface.getNode(args.dest).localConfig - prefs.lora.modem_preset = modem_preset - interface.getNode(args.dest).writeConfig("lora") + node = interface.getNode(args.dest, False) + if len(node.localConfig.ListFields()) == 0: + node.requestConfig(node.localConfig.DESCRIPTOR.fields_by_name.get("lora")) + node.localConfig.lora.modem_preset = modem_preset + node.writeConfig("lora") # handle the simple radio set commands if args.ch_vlongslow: From 0aac077ce7d756eae489607718a6df0bb1a851d4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Sep 2024 16:05:25 +0000 Subject: [PATCH 214/248] bump version to 2.4.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 538cb64..b3cc98f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.2a0" +version = "2.4.2" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 33a13f715e2538ec5a85fb62992337956313e636 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 11 Sep 2024 09:12:41 -0700 Subject: [PATCH 215/248] 2.4.3 prep (protobufs, alpha version) --- meshtastic/protobuf/admin_pb2.py | 20 ++++++++++---------- meshtastic/protobuf/admin_pb2.pyi | 20 +++++++++++++------- meshtastic/protobuf/mesh_pb2.py | 12 ++++++------ meshtastic/protobuf/mesh_pb2.pyi | 26 ++++++++++++++++++++++++++ meshtastic/protobuf/telemetry_pb2.py | 4 ++-- meshtastic/protobuf/telemetry_pb2.pyi | 24 ++++++++++++++++++++++++ protobufs | 2 +- pyproject.toml | 2 +- 8 files changed, 83 insertions(+), 27 deletions(-) diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index c002b8f..bc68a74 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -18,7 +18,7 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xea\x12\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\x91\x13\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,13 +27,13 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_ADMINMESSAGE']._serialized_start=244 - _globals['_ADMINMESSAGE']._serialized_end=2654 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2168 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2317 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2320 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2635 - _globals['_HAMPARAMETERS']._serialized_start=2656 - _globals['_HAMPARAMETERS']._serialized_end=2747 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2749 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2860 + _globals['_ADMINMESSAGE']._serialized_end=2693 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=2207 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=2356 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=2359 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=2674 + _globals['_HAMPARAMETERS']._serialized_start=2695 + _globals['_HAMPARAMETERS']._serialized_end=2786 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=2788 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=2899 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index 0840385..e687f01 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -255,11 +255,12 @@ class AdminMessage(google.protobuf.message.Message): REMOVE_FIXED_POSITION_FIELD_NUMBER: builtins.int BEGIN_EDIT_SETTINGS_FIELD_NUMBER: builtins.int COMMIT_EDIT_SETTINGS_FIELD_NUMBER: builtins.int + FACTORY_RESET_DEVICE_FIELD_NUMBER: builtins.int REBOOT_OTA_SECONDS_FIELD_NUMBER: builtins.int EXIT_SIMULATOR_FIELD_NUMBER: builtins.int REBOOT_SECONDS_FIELD_NUMBER: builtins.int SHUTDOWN_SECONDS_FIELD_NUMBER: builtins.int - FACTORY_RESET_FIELD_NUMBER: builtins.int + FACTORY_RESET_CONFIG_FIELD_NUMBER: builtins.int NODEDB_RESET_FIELD_NUMBER: builtins.int get_channel_request: builtins.int """ @@ -352,6 +353,10 @@ class AdminMessage(google.protobuf.message.Message): """ Commits an open transaction for any edits made to config, module config, owner, and channel settings """ + factory_reset_device: builtins.int + """ + Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. + """ reboot_ota_seconds: builtins.int """ Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) @@ -370,9 +375,9 @@ class AdminMessage(google.protobuf.message.Message): """ Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) """ - factory_reset: builtins.int + factory_reset_config: builtins.int """ - Tell the node to factory reset, all device settings will be returned to factory defaults. + Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. """ nodedb_reset: builtins.int """ @@ -498,16 +503,17 @@ class AdminMessage(google.protobuf.message.Message): remove_fixed_position: builtins.bool = ..., begin_edit_settings: builtins.bool = ..., commit_edit_settings: builtins.bool = ..., + factory_reset_device: builtins.int = ..., reboot_ota_seconds: builtins.int = ..., exit_simulator: builtins.bool = ..., reboot_seconds: builtins.int = ..., shutdown_seconds: builtins.int = ..., - factory_reset: builtins.int = ..., + factory_reset_config: builtins.int = ..., nodedb_reset: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["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", b"factory_reset", "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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> 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", "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", "begin_edit_settings", "commit_edit_settings", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset", "nodedb_reset"] | None: ... + def HasField(self, field_name: typing.Literal["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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["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", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "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_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "shutdown_seconds", b"shutdown_seconds"]) -> 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", "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", "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 diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 32f4706..96da1c0 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xd0\n\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\xf7\x05\n\x08Position\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\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x14\n\x0c\x61ltitude_hae\x18\t \x01(\x11\x12#\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x14\n\x0cground_speed\x18\x0f \x01(\r\x12\x14\n\x0cground_track\x18\x10 \x01(\r\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\"\xd6\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\"\x97\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xca\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"\xb0\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\"\x93\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\nlatitude_i\x18\x02 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x03 \x01(\x0f\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf1\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x42\x11\n\x0fpayload_variant\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x85\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,11 +32,11 @@ if _descriptor._USE_C_DESCRIPTORS == False: _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' _globals['_HARDWAREMODEL']._serialized_start=5544 - _globals['_HARDWAREMODEL']._serialized_end=6904 - _globals['_CONSTANTS']._serialized_start=6906 - _globals['_CONSTANTS']._serialized_end=6950 - _globals['_CRITICALERRORCODE']._serialized_start=6953 - _globals['_CRITICALERRORCODE']._serialized_end=7261 + _globals['_HARDWAREMODEL']._serialized_end=6957 + _globals['_CONSTANTS']._serialized_start=6959 + _globals['_CONSTANTS']._serialized_end=7003 + _globals['_CRITICALERRORCODE']._serialized_start=7006 + _globals['_CRITICALERRORCODE']._serialized_end=7314 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1032 _globals['_POSITION_LOCSOURCE']._serialized_start=854 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 2e56b48..6f1e3ef 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -332,6 +332,19 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. """ + RAK3172: _HardwareModel.ValueType # 72 + """ + RAK3172 STM32WLE5 Module (https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172) + """ + WIO_E5: _HardwareModel.ValueType # 73 + """ + Seeed Studio Wio-E5 (either mini or Dev kit) using STM32WL chip. + """ + RADIOMASTER_900_BANDIT: _HardwareModel.ValueType # 74 + """ + RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module + SSD1306 OLED and No GPS + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -648,6 +661,19 @@ TRACKER_T1000_E: HardwareModel.ValueType # 71 """ Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors. """ +RAK3172: HardwareModel.ValueType # 72 +""" +RAK3172 STM32WLE5 Module (https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172) +""" +WIO_E5: HardwareModel.ValueType # 73 +""" +Seeed Studio Wio-E5 (either mini or Dev kit) using STM32WL chip. +""" +RADIOMASTER_900_BANDIT: HardwareModel.ValueType # 74 +""" +RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module +SSD1306 OLED and No GPS +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 14b5351..3c46fee 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xdc\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\x12\x11\n\twind_gust\x18\x10 \x01(\x02\x12\x11\n\twind_lull\x18\x11 \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xea\x02\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\x81\x01\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\x12\x16\n\x0euptime_seconds\x18\x05 \x01(\r\"\xdc\x02\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\x12\x0b\n\x03iaq\x18\x07 \x01(\r\x12\x10\n\x08\x64istance\x18\x08 \x01(\x02\x12\x0b\n\x03lux\x18\t \x01(\x02\x12\x11\n\twhite_lux\x18\n \x01(\x02\x12\x0e\n\x06ir_lux\x18\x0b \x01(\x02\x12\x0e\n\x06uv_lux\x18\x0c \x01(\x02\x12\x16\n\x0ewind_direction\x18\r \x01(\r\x12\x12\n\nwind_speed\x18\x0e \x01(\x02\x12\x0e\n\x06weight\x18\x0f \x01(\x02\x12\x11\n\twind_gust\x18\x10 \x01(\x02\x12\x11\n\twind_lull\x18\x11 \x01(\x02\"\x8c\x01\n\x0cPowerMetrics\x12\x13\n\x0b\x63h1_voltage\x18\x01 \x01(\x02\x12\x13\n\x0b\x63h1_current\x18\x02 \x01(\x02\x12\x13\n\x0b\x63h2_voltage\x18\x03 \x01(\x02\x12\x13\n\x0b\x63h2_current\x18\x04 \x01(\x02\x12\x13\n\x0b\x63h3_voltage\x18\x05 \x01(\x02\x12\x13\n\x0b\x63h3_current\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xad\x02\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\x92\x03\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x42\x64\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -22,7 +22,7 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_TELEMETRYSENSORTYPE']._serialized_start=1377 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=1739 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=1779 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=190 _globals['_ENVIRONMENTMETRICS']._serialized_start=193 diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index 83334ec..e63c9ee 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -127,6 +127,18 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ NAU7802 Scale Chip or compatible """ + BMP3XX: _TelemetrySensorType.ValueType # 26 + """ + BMP3XX High accuracy temperature and pressure + """ + ICM20948: _TelemetrySensorType.ValueType # 27 + """ + ICM-20948 9-Axis digital motion processor + """ + MAX17048: _TelemetrySensorType.ValueType # 28 + """ + MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -237,6 +249,18 @@ NAU7802: TelemetrySensorType.ValueType # 25 """ NAU7802 Scale Chip or compatible """ +BMP3XX: TelemetrySensorType.ValueType # 26 +""" +BMP3XX High accuracy temperature and pressure +""" +ICM20948: TelemetrySensorType.ValueType # 27 +""" +ICM-20948 9-Axis digital motion processor +""" +MAX17048: TelemetrySensorType.ValueType # 28 +""" +MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) +""" global___TelemetrySensorType = TelemetrySensorType @typing.final diff --git a/protobufs b/protobufs index d0fe91a..666b481 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit d0fe91ab99734cacdc188403f73fe30f766917cf +Subproject commit 666b481ae02f1f88ec30f10a2d80184b31c0fc4e diff --git a/pyproject.toml b/pyproject.toml index b3cc98f..4e614b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.2" +version = "2.4.3a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 9423a8a8b9356f66e6aaaca5e53ec1414a00c3e3 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Sep 2024 16:16:12 +0000 Subject: [PATCH 216/248] bump version to 2.4.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4e614b2..f11c208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.4.3a0" +version = "2.4.3" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 21ff4a1a4a4e324c4b5f6b532df0aae3104d5022 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 11 Sep 2024 09:40:26 -0700 Subject: [PATCH 217/248] Split factory reset into two variants --- meshtastic/__main__.py | 15 +++++++++++---- meshtastic/node.py | 10 +++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3184d2a..eafb492 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -416,10 +416,11 @@ def onConnected(interface): closeNow = True interface.getNode(args.dest, False).commitSettingsTransaction() - if args.factory_reset: + if args.factory_reset or args.factory_reset_device: closeNow = True waitForAckNak = True - interface.getNode(args.dest, False).factoryReset() + full = bool(args.factory_reset_device) + interface.getNode(args.dest, False).factoryReset(full=full) if args.remove_node: closeNow = True @@ -1549,8 +1550,14 @@ def initParser(): ) group.add_argument( - "--factory-reset", - help="Tell the destination node to install the default config", + "--factory-reset", "--factory-reset-config", + help="Tell the destination node to install the default config, preserving BLE bonds & PKI keys", + action="store_true", + ) + + group.add_argument( + "--factory-reset-device", + help="Tell the destination node to install the default config and clear BLE bonds & PKI keys", action="store_true", ) diff --git a/meshtastic/node.py b/meshtastic/node.py index ca1977c..415154d 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -629,12 +629,16 @@ class Node: ) self.iface.waitForAckNak() - def factoryReset(self): + def factoryReset(self, full: bool = False): """Tell the node to factory reset.""" self.ensureSessionKey() p = admin_pb2.AdminMessage() - p.factory_reset = True - logging.info(f"Telling node to factory reset") + if full: + p.factory_reset_device = True + logging.info(f"Telling node to factory reset (full device reset)") + else: + p.factory_reset_config = True + 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: From 3bbd02c915df705be3bdd3b703d7648e97cb249d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 11 Sep 2024 16:34:03 -0700 Subject: [PATCH 218/248] Detect repeating fields using field labels, enabling admin key to be set --- meshtastic/__main__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index eafb492..3ffbc06 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -233,8 +233,8 @@ def setPref(config, comp_name, valStr) -> bool: print(f" {temp_name}") return False - # note: 'ignore_incoming' is a repeating field - if snake_name != "ignore_incoming": + # repeating fields need to be handled with append, not setattr + if pref.label != pref.LABEL_REPEATED: try: if config_type.message_type is not None: config_values = getattr(config_part, config_type.name) @@ -249,11 +249,11 @@ def setPref(config, comp_name, valStr) -> bool: config_values = getattr(config, config_type.name) if val == 0: # clear values - print("Clearing ignore_incoming list") - del config_values.ignore_incoming[:] + print(f"Clearing {pref.name} list") + del getattr(config_values, pref.name)[:] else: - print(f"Adding '{val}' to the ignore_incoming list") - config_values.ignore_incoming.extend([int(valStr)]) + print(f"Adding '{val}' to the {pref.name} list") + getattr(config_values, pref.name).append(val) prefix = f"{'.'.join(name[0:-1])}." if config_type.message_type is not None else "" if mt_config.camel_case: From cc2067b729faf7c4da39af2bb1d1f606f5c6f4ed Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 11 Sep 2024 17:10:04 -0700 Subject: [PATCH 219/248] clean up settings response to use CopyFrom to be better at repeated and nested fields --- meshtastic/node.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meshtastic/node.py b/meshtastic/node.py index 415154d..52f6aae 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -98,6 +98,7 @@ class Node: print("") adminMessage = p["decoded"]["admin"] if "getConfigResponse" in adminMessage: + oneof = "get_config_response" resp = adminMessage["getConfigResponse"] field = list(resp.keys())[0] config_type = self.localConfig.DESCRIPTOR.fields_by_name.get( @@ -106,6 +107,7 @@ class Node: if config_type is not None: config_values = getattr(self.localConfig, config_type.name) elif "getModuleConfigResponse" in adminMessage: + oneof = "get_module_config_response" resp = adminMessage["getModuleConfigResponse"] field = list(resp.keys())[0] config_type = self.moduleConfig.DESCRIPTOR.fields_by_name.get( @@ -118,8 +120,8 @@ class Node: ) return if config_values is not None: - for key, value in resp[field].items(): - setattr(config_values, camel_to_snake(key), value) + raw_config = getattr(getattr(adminMessage['raw'], oneof), field) + config_values.CopyFrom(raw_config) print(f"{str(camel_to_snake(field))}:\n{str(config_values)}") def requestConfig(self, configType): From f7724295f93dfcef2c59591946614477754e639b Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 12 Sep 2024 16:27:45 +0000 Subject: [PATCH 220/248] bump version to 2.5.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a8366ce..39ff255 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.5.0a0" +version = "2.5.0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From abe1dd47caf3dc33485192ba01b72a7b89131d4a Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 11:36:23 -0500 Subject: [PATCH 221/248] add type to argument --- meshtastic/__main__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index fcfb385..a484eb5 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -275,8 +275,8 @@ def onConnected(interface): # convenient place to store any keyword args we pass to getNode getNode_kwargs = { - "requestChannelRetries": int(args.channel_fetch_retries), - "timeout": int(args.timeout) + "requestChannelRetries": args.channel_fetch_retries, + "timeout": args.timeout } # do not print this line if we are exporting the config @@ -1433,12 +1433,14 @@ def initParser(): "--channel-fetch-retries", help=("Attempt to retrieve channel settings for --ch-set this many times before giving up."), default=3, + type=int, ) group.add_argument( "--timeout", help="How long to wait for replies", - default=300 + default=300, + type=int, ) group.add_argument( From 44cfd72a80e7991b7a62c77fb244455fbf44192d Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 11:39:10 -0500 Subject: [PATCH 222/248] make sure new_index is always an int --- meshtastic/mesh_interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 48fff56..8c9679d 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -330,14 +330,14 @@ class MeshInterface: # pylint: disable=R0902 while retries_left > 0: retries_left -= 1 if not n.waitForConfig(): - new_index: int = len(n.partialChannels) + new_index: int = len(n.partialChannels) if n.partialChannels else 0 # each time we get a new channel, reset the counter if new_index != last_index: retries_left = requestChannelRetries - 1 if retries_left <= 0: our_exit(f"Error: Timed out waiting for channels, giving up") print("Timed out trying to retrieve channel info, retrying") - n.requestChannels(startingIndex=len(n.partialChannels)) + n.requestChannels(startingIndex=new_index) last_index = new_index else: break From 1967519deb5f1bad03a2cad6fb8a30cfc4e6fc72 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 11:52:27 -0500 Subject: [PATCH 223/248] correct type issue during initial assignment --- meshtastic/node.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meshtastic/node.py b/meshtastic/node.py index 4b4303f..278ea8a 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -5,7 +5,7 @@ import base64 import logging import time -from typing import Optional, Union +from typing import Optional, Union, List from meshtastic.protobuf import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2 from meshtastic.util import ( @@ -33,7 +33,7 @@ class Node: self.moduleConfig = localonly_pb2.LocalModuleConfig() self.channels = None self._timeout = Timeout(maxSecs=timeout) - self.partialChannels = None + self.partialChannels: Optional[List] = None self.noProto = noProto self.cannedPluginMessage = None self.cannedPluginMessageMessages = None From aa74db46cb46bb817118cd05da19697f92a1cf8f Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 11:59:03 -0500 Subject: [PATCH 224/248] update message check in test to reflect new message --- meshtastic/tests/test_mesh_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 21f80c6..cace7eb 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -173,7 +173,7 @@ def test_getNode_not_local_timeout(capsys): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - assert re.match(r"Error: Timed out waiting for channels", out) + assert re.match(r"Timed out trying to retrieve channel info, retrying", out) assert err == "" From 9e7d5e96abe07ca46542225a22dcd2b301263a4c Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 12:03:51 -0500 Subject: [PATCH 225/248] Rename "retries" to "attempts" Otherwise, semantically, it's off-by-one. --- meshtastic/__main__.py | 4 ++-- meshtastic/mesh_interface.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 6ae3821..68c785c 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -275,7 +275,7 @@ def onConnected(interface): # convenient place to store any keyword args we pass to getNode getNode_kwargs = { - "requestChannelRetries": args.channel_fetch_retries, + "requestChannelRetries": args.channel_fetch_attempts, "timeout": args.timeout } @@ -1416,7 +1416,7 @@ def initParser(): ) group.add_argument( - "--channel-fetch-retries", + "--channel-fetch-attempts", help=("Attempt to retrieve channel settings for --ch-set this many times before giving up."), default=3, type=int, diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 86e4e80..872c7f0 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -315,7 +315,7 @@ class MeshInterface: # pylint: disable=R0902 return table def getNode( - self, nodeId: str, requestChannels: bool = True, requestChannelRetries: int = 3, timeout: int = 300 + self, nodeId: str, requestChannels: bool = True, requestChannelAttempts: int = 3, timeout: int = 300 ) -> meshtastic.node.Node: """Return a node object which contains device settings and channel info""" if nodeId in (LOCAL_ADDR, BROADCAST_ADDR): @@ -326,7 +326,7 @@ class MeshInterface: # pylint: disable=R0902 if requestChannels: logging.debug("About to requestChannels") n.requestChannels() - retries_left = requestChannelRetries + retries_left = requestChannelAttempts last_index: int = 0 while retries_left > 0: retries_left -= 1 @@ -334,7 +334,7 @@ class MeshInterface: # pylint: disable=R0902 new_index: int = len(n.partialChannels) if n.partialChannels else 0 # each time we get a new channel, reset the counter if new_index != last_index: - retries_left = requestChannelRetries - 1 + retries_left = requestChannelAttempts - 1 if retries_left <= 0: our_exit(f"Error: Timed out waiting for channels, giving up") print("Timed out trying to retrieve channel info, retrying") From 62f5201a38fd62bddea656680f8e51379d310242 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 12:04:22 -0500 Subject: [PATCH 226/248] Add test covering retry logic --- meshtastic/tests/test_mesh_interface.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index cace7eb..bacf85c 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -176,6 +176,22 @@ def test_getNode_not_local_timeout(capsys): assert re.match(r"Timed out trying to retrieve channel info, retrying", out) assert err == "" +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_getNode_not_local_timeout_attempts(capsys): + """Test getNode not local, simulate timeout""" + iface = MeshInterface(noProto=True) + anode = MagicMock(autospec=Node) + anode.waitForConfig.return_value = False + with patch("meshtastic.node.Node", return_value=anode): + with pytest.raises(SystemExit) as pytest_wrapped_e: + iface.getNode("bar2", requestChannelAttempts=2) + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + out, err = capsys.readouterr() + assert out == 'Timed out trying to retrieve channel info, retrying\nError: Timed out waiting for channels, giving up\n' + assert err == "" + @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") From 8f2c397fbfaf89f9378b98536332bc0203eb35aa Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 14:01:41 -0500 Subject: [PATCH 227/248] =?UTF-8?q?missed=20one=20reference=20for=20reques?= =?UTF-8?q?tChannelRetries=20=F0=9F=A4=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meshtastic/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 68c785c..77424c8 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -275,7 +275,7 @@ def onConnected(interface): # convenient place to store any keyword args we pass to getNode getNode_kwargs = { - "requestChannelRetries": args.channel_fetch_attempts, + "requestChannelAttempts": args.channel_fetch_attempts, "timeout": args.timeout } From 73a1bbc7d59ce27ae938a9ad50108bb360ccf8a9 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 16:02:59 -0500 Subject: [PATCH 228/248] add test coverage for changes to requestChannels --- meshtastic/tests/test_node.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index 5361296..668fd4d 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -842,6 +842,32 @@ def test_requestChannel_localNode(caplog): assert re.search(r"Requesting channel 0", caplog.text, re.MULTILINE) assert not re.search(r"from remote node", caplog.text, re.MULTILINE) +@pytest.mark.unit +def test_requestChannels_non_localNode(caplog): + iface = MagicMock(autospec=SerialInterface) + with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: + mo.localNode.getChannelByName.return_value = None + mo.myInfo.max_channels = 8 + anode = Node(mo, "bar", noProto=True) + anode.partialChannels = ['0'] + with caplog.at_level(logging.DEBUG): + anode.requestChannels(0) + assert re.search(f"Requesting channel 0 info from remote node", caplog.text, re.MULTILINE) + assert anode.partialChannels == [] + +@pytest.mark.unit +def test_requestChannels_non_localNode_starting_index(caplog): + iface = MagicMock(autospec=SerialInterface) + with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: + mo.localNode.getChannelByName.return_value = None + mo.myInfo.max_channels = 8 + anode = Node(mo, "bar", noProto=True) + anode.partialChannels = ['1'] + with caplog.at_level(logging.DEBUG): + anode.requestChannels(3) + assert re.search(f"Requesting channel 3 info from remote node", caplog.text, re.MULTILINE) + # make sure it hasn't been initialized + assert anode.partialChannels == ['1'] # @pytest.mark.unit # def test_onResponseRequestCannedMessagePluginMesagePart1(caplog): From e561222ea70045bef48443c795c6d66cf30864ee Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 16:06:44 -0500 Subject: [PATCH 229/248] add docstrings --- meshtastic/tests/test_node.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index 668fd4d..61ab84a 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -844,6 +844,7 @@ def test_requestChannel_localNode(caplog): @pytest.mark.unit def test_requestChannels_non_localNode(caplog): + """Test requestChannels() with a starting index of 0""" iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: mo.localNode.getChannelByName.return_value = None @@ -857,6 +858,7 @@ def test_requestChannels_non_localNode(caplog): @pytest.mark.unit def test_requestChannels_non_localNode_starting_index(caplog): + """Test requestChannels() with a starting index of non-0""" iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: mo.localNode.getChannelByName.return_value = None From 34f9be255e1094784f15d1fdff1cb43744b3f283 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 16:20:50 -0500 Subject: [PATCH 230/248] fix unrelated bug when fromStr input is short hex For example, 0x0 will generate an unhandled ValueError. This was caught during a random unit test run for 3.9, so I figure I'd fix it. This is unrelated to the PR otherwise. --- meshtastic/tests/test_util.py | 8 ++++++++ meshtastic/util.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index 09f67fe..ac8fa15 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -650,3 +650,11 @@ def test_fuzz_fromStr(valstr): assert isinstance(result, int) except ValueError: assert isinstance(result, str) + +def test_shorthex(): + result = fromStr('0x0') + assert result == b'\x00' + result = fromStr('0x5') + assert result == b'\x05' + result = fromStr('0xffff') + assert result == b'\xff\xff' \ No newline at end of file diff --git a/meshtastic/util.py b/meshtastic/util.py index 8cb177c..3f864a2 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -82,7 +82,7 @@ def fromStr(valstr): val = bytes() elif valstr.startswith("0x"): # if needed convert to string with asBytes.decode('utf-8') - val = bytes.fromhex(valstr[2:]) + val = bytes.fromhex(valstr[2:].zfill(2)) elif valstr.startswith("base64:"): val = base64.b64decode(valstr[7:]) elif valstr.lower() in {"t", "true", "yes"}: From 2026212a00665aea576937055b22309f8cb38c24 Mon Sep 17 00:00:00 2001 From: Derek Arnold Date: Sun, 15 Sep 2024 16:27:40 -0500 Subject: [PATCH 231/248] please pylint with a docstring and newline --- meshtastic/tests/test_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index ac8fa15..236e787 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -652,9 +652,10 @@ def test_fuzz_fromStr(valstr): assert isinstance(result, str) def test_shorthex(): + """Test the shortest hex string representations""" result = fromStr('0x0') assert result == b'\x00' result = fromStr('0x5') assert result == b'\x05' result = fromStr('0xffff') - assert result == b'\xff\xff' \ No newline at end of file + assert result == b'\xff\xff' From bf904c69068bfc2c4b544673e48a74e3d8b08a2f Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Mon, 16 Sep 2024 23:24:03 -0600 Subject: [PATCH 232/248] Allow port number to be specified with tcp hostname --- meshtastic/__main__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 02d9abc..8aff798 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1155,8 +1155,14 @@ def common(): ) elif args.host: try: + if ":" in args.host: + tcp_hostname, tcp_port = args.host.split(':') + else: + tcp_hostname = args.host + tcp_port = 4403 client = meshtastic.tcp_interface.TCPInterface( - args.host, + tcp_hostname, + portNumber=tcp_port, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes, From 5cc9627e218501599295da3198059e9cf782687a Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Mon, 16 Sep 2024 23:41:44 -0600 Subject: [PATCH 233/248] Refactor default port number to variable --- meshtastic/__main__.py | 2 +- meshtastic/tcp_interface.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 8aff798..a2b0e5c 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1159,7 +1159,7 @@ def common(): tcp_hostname, tcp_port = args.host.split(':') else: tcp_hostname = args.host - tcp_port = 4403 + tcp_port = meshtastic.tcp_interface.DEFAULT_TCP_PORT client = meshtastic.tcp_interface.TCPInterface( tcp_hostname, portNumber=tcp_port, diff --git a/meshtastic/tcp_interface.py b/meshtastic/tcp_interface.py index d049dc4..7b588c6 100644 --- a/meshtastic/tcp_interface.py +++ b/meshtastic/tcp_interface.py @@ -6,6 +6,7 @@ from typing import Optional from meshtastic.stream_interface import StreamInterface +DEFAULT_TCP_PORT = 4403 class TCPInterface(StreamInterface): """Interface class for meshtastic devices over a TCP link""" @@ -16,7 +17,7 @@ class TCPInterface(StreamInterface): debugOut=None, noProto=False, connectNow=True, - portNumber=4403, + portNumber=DEFAULT_TCP_PORT, noNodes:bool=False, ): """Constructor, opens a connection to a specified IP address/hostname From 4fdbcb967935053c49926ae4b7826bac7f854811 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 17 Sep 2024 21:10:57 -0700 Subject: [PATCH 234/248] Fix test_fuzz_fromStr for floats --- meshtastic/tests/test_util.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index 236e787..0124ba6 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -649,7 +649,11 @@ def test_fuzz_fromStr(valstr): int(valstr) assert isinstance(result, int) except ValueError: - assert isinstance(result, str) + try: + float(valstr) + assert isinstance(result, float) + except ValueError: + assert isinstance(result, str) def test_shorthex(): """Test the shortest hex string representations""" From c696d59b9052361856630c8eb97a061cdb51dc6b Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 17 Sep 2024 21:52:57 -0700 Subject: [PATCH 235/248] Set list-type keys differently, excluding 0-like values and resetting whole list --- meshtastic/__main__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index a9fb788..8eb04eb 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -253,7 +253,9 @@ def setPref(config, comp_name, valStr) -> bool: del getattr(config_values, pref.name)[:] else: print(f"Adding '{val}' to the {pref.name} list") - getattr(config_values, pref.name).append(val) + cur_vals = [x for x in getattr(config_values, pref.name) if x not in [0, "", b""]] + cur_vals.append(val) + getattr(config_values, pref.name)[:] = cur_vals prefix = f"{'.'.join(name[0:-1])}." if config_type.message_type is not None else "" if mt_config.camel_case: From 48a06c6e1e5d053722aa006664062c69073d6980 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Wed, 18 Sep 2024 14:58:05 -0700 Subject: [PATCH 236/248] protobufs & alpha version number: v2.5.1 --- meshtastic/protobuf/atak_pb2.py | 32 +++---- meshtastic/protobuf/atak_pb2.pyi | 13 ++- meshtastic/protobuf/clientonly_pb2.py | 7 +- meshtastic/protobuf/clientonly_pb2.pyi | 31 ++++++- meshtastic/protobuf/deviceonly_pb2.py | 20 ++--- meshtastic/protobuf/deviceonly_pb2.pyi | 7 +- meshtastic/protobuf/mesh_pb2.py | 114 ++++++++++++------------- meshtastic/protobuf/mesh_pb2.pyi | 31 ++++++- protobufs | 2 +- pyproject.toml | 2 +- 10 files changed, 159 insertions(+), 100 deletions(-) diff --git a/meshtastic/protobuf/atak_pb2.py b/meshtastic/protobuf/atak_pb2.py index aec03c3..d2b9e9a 100644 --- a/meshtastic/protobuf/atak_pb2.py +++ b/meshtastic/protobuf/atak_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\x93\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\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') +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) @@ -21,20 +21,20 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.atak_pb if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None 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=703 - _globals['_TEAM']._serialized_end=895 - _globals['_MEMBERROLE']._serialized_start=897 - _globals['_MEMBERROLE']._serialized_end=1024 + _globals['_TEAM']._serialized_start=721 + _globals['_TEAM']._serialized_end=913 + _globals['_MEMBERROLE']._serialized_start=915 + _globals['_MEMBERROLE']._serialized_end=1042 _globals['_TAKPACKET']._serialized_start=56 - _globals['_TAKPACKET']._serialized_end=331 - _globals['_GEOCHAT']._serialized_start=333 - _globals['_GEOCHAT']._serialized_end=425 - _globals['_GROUP']._serialized_start=427 - _globals['_GROUP']._serialized_end=522 - _globals['_STATUS']._serialized_start=524 - _globals['_STATUS']._serialized_end=549 - _globals['_CONTACT']._serialized_start=551 - _globals['_CONTACT']._serialized_end=603 - _globals['_PLI']._serialized_start=605 - _globals['_PLI']._serialized_end=700 + _globals['_TAKPACKET']._serialized_end=349 + _globals['_GEOCHAT']._serialized_start=351 + _globals['_GEOCHAT']._serialized_end=443 + _globals['_GROUP']._serialized_start=445 + _globals['_GROUP']._serialized_end=540 + _globals['_STATUS']._serialized_start=542 + _globals['_STATUS']._serialized_end=567 + _globals['_CONTACT']._serialized_start=569 + _globals['_CONTACT']._serialized_end=621 + _globals['_PLI']._serialized_start=623 + _globals['_PLI']._serialized_end=718 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/atak_pb2.pyi b/meshtastic/protobuf/atak_pb2.pyi index 4471e17..2362667 100644 --- a/meshtastic/protobuf/atak_pb2.pyi +++ b/meshtastic/protobuf/atak_pb2.pyi @@ -248,10 +248,16 @@ class TAKPacket(google.protobuf.message.Message): STATUS_FIELD_NUMBER: builtins.int PLI_FIELD_NUMBER: builtins.int CHAT_FIELD_NUMBER: builtins.int + DETAIL_FIELD_NUMBER: builtins.int is_compressed: builtins.bool """ Are the payloads strings compressed for LoRA transport? """ + detail: builtins.bytes + """ + Generic CoT detail XML + May be compressed / truncated by the sender + """ @property def contact(self) -> global___Contact: """ @@ -291,10 +297,11 @@ class TAKPacket(google.protobuf.message.Message): status: global___Status | None = ..., pli: global___PLI | None = ..., chat: global___GeoChat | None = ..., + detail: builtins.bytes = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "group", b"group", "is_compressed", b"is_compressed", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["pli", "chat"] | None: ... + def HasField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "detail", b"detail", "group", b"group", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["chat", b"chat", "contact", b"contact", "detail", b"detail", "group", b"group", "is_compressed", b"is_compressed", "payload_variant", b"payload_variant", "pli", b"pli", "status", b"status"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["pli", "chat", "detail"] | None: ... global___TAKPacket = TAKPacket diff --git a/meshtastic/protobuf/clientonly_pb2.py b/meshtastic/protobuf/clientonly_pb2.py index 702bca7..bd336a0 100644 --- a/meshtastic/protobuf/clientonly_pb2.py +++ b/meshtastic/protobuf/clientonly_pb2.py @@ -12,9 +12,10 @@ _sym_db = _symbol_database.Default() 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 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\"\x9f\x02\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\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configBe\n\x13\x63om.geeksville.meshB\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) @@ -22,6 +23,6 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cliento if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None 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=99 - _globals['_DEVICEPROFILE']._serialized_end=386 + _globals['_DEVICEPROFILE']._serialized_start=131 + _globals['_DEVICEPROFILE']._serialized_end=583 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/clientonly_pb2.pyi b/meshtastic/protobuf/clientonly_pb2.pyi index 7b3028c..78725be 100644 --- a/meshtastic/protobuf/clientonly_pb2.pyi +++ b/meshtastic/protobuf/clientonly_pb2.pyi @@ -7,6 +7,7 @@ import builtins import google.protobuf.descriptor import google.protobuf.message import meshtastic.protobuf.localonly_pb2 +import meshtastic.protobuf.mesh_pb2 import typing DESCRIPTOR: google.protobuf.descriptor.FileDescriptor @@ -25,6 +26,9 @@ class DeviceProfile(google.protobuf.message.Message): CHANNEL_URL_FIELD_NUMBER: builtins.int CONFIG_FIELD_NUMBER: builtins.int MODULE_CONFIG_FIELD_NUMBER: builtins.int + FIXED_POSITION_FIELD_NUMBER: builtins.int + RINGTONE_FIELD_NUMBER: builtins.int + CANNED_MESSAGES_FIELD_NUMBER: builtins.int long_name: builtins.str """ Long name for the node @@ -37,6 +41,14 @@ class DeviceProfile(google.protobuf.message.Message): """ The url of the channels from our node """ + ringtone: builtins.str + """ + Ringtone for ExternalNotification + """ + canned_messages: builtins.str + """ + Predefined messages for CannedMessage + """ @property def config(self) -> meshtastic.protobuf.localonly_pb2.LocalConfig: """ @@ -49,6 +61,12 @@ class DeviceProfile(google.protobuf.message.Message): The ModuleConfig of the node """ + @property + def fixed_position(self) -> meshtastic.protobuf.mesh_pb2.Position: + """ + Fixed position data + """ + def __init__( self, *, @@ -57,18 +75,27 @@ class DeviceProfile(google.protobuf.message.Message): channel_url: builtins.str | None = ..., config: meshtastic.protobuf.localonly_pb2.LocalConfig | None = ..., module_config: meshtastic.protobuf.localonly_pb2.LocalModuleConfig | None = ..., + fixed_position: meshtastic.protobuf.mesh_pb2.Position | None = ..., + ringtone: builtins.str | None = ..., + canned_messages: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["_channel_url", b"_channel_url", "_config", b"_config", "_long_name", b"_long_name", "_module_config", b"_module_config", "_short_name", b"_short_name", "channel_url", b"channel_url", "config", b"config", "long_name", b"long_name", "module_config", b"module_config", "short_name", b"short_name"]) -> None: ... + def HasField(self, field_name: typing.Literal["_canned_messages", b"_canned_messages", "_channel_url", b"_channel_url", "_config", b"_config", "_fixed_position", b"_fixed_position", "_long_name", b"_long_name", "_module_config", b"_module_config", "_ringtone", b"_ringtone", "_short_name", b"_short_name", "canned_messages", b"canned_messages", "channel_url", b"channel_url", "config", b"config", "fixed_position", b"fixed_position", "long_name", b"long_name", "module_config", b"module_config", "ringtone", b"ringtone", "short_name", b"short_name"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_canned_messages", b"_canned_messages", "_channel_url", b"_channel_url", "_config", b"_config", "_fixed_position", b"_fixed_position", "_long_name", b"_long_name", "_module_config", b"_module_config", "_ringtone", b"_ringtone", "_short_name", b"_short_name", "canned_messages", b"canned_messages", "channel_url", b"channel_url", "config", b"config", "fixed_position", b"fixed_position", "long_name", b"long_name", "module_config", b"module_config", "ringtone", b"ringtone", "short_name", b"short_name"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_canned_messages", b"_canned_messages"]) -> typing.Literal["canned_messages"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_channel_url", b"_channel_url"]) -> typing.Literal["channel_url"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_config", b"_config"]) -> typing.Literal["config"] | None: ... @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_fixed_position", b"_fixed_position"]) -> typing.Literal["fixed_position"] | None: ... + @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_long_name", b"_long_name"]) -> typing.Literal["long_name"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_module_config", b"_module_config"]) -> typing.Literal["module_config"] | None: ... @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_ringtone", b"_ringtone"]) -> typing.Literal["ringtone"] | None: ... + @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_short_name", b"_short_name"]) -> typing.Literal["short_name"] | None: ... global___DeviceProfile = DeviceProfile diff --git a/meshtastic/protobuf/deviceonly_pb2.py b/meshtastic/protobuf/deviceonly_pb2.py index 31f1c68..2d122a8 100644 --- a/meshtastic/protobuf/deviceonly_pb2.py +++ b/meshtastic/protobuf/deviceonly_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config 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/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/config.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\"\xa5\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\x82\x04\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\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\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\x12\x63\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"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\"\xb2\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x32\n\x08oem_font\x18\x04 \x01(\x0e\x32 .meshtastic.protobuf.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12:\n\x10oem_local_config\x18\x07 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12G\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/config.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\"\xb8\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\x42\x0c\n\n_hops_away\"\x82\x04\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\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\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\x12\x63\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"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\"\xb2\x02\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x32\n\x08oem_font\x18\x04 \x01(\x0e\x32 .meshtastic.protobuf.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12:\n\x10oem_local_config\x18\x07 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12G\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,18 +33,18 @@ if _descriptor._USE_C_DESCRIPTORS == False: _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' _DEVICESTATE.fields_by_name['node_db_lite']._options = None _DEVICESTATE.fields_by_name['node_db_lite']._serialized_options = b'\222?\'\222\001$std::vector' - _globals['_SCREENFONTS']._serialized_start=1837 - _globals['_SCREENFONTS']._serialized_end=1899 + _globals['_SCREENFONTS']._serialized_start=1856 + _globals['_SCREENFONTS']._serialized_end=1918 _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=929 - _globals['_DEVICESTATE']._serialized_start=932 - _globals['_DEVICESTATE']._serialized_end=1446 - _globals['_CHANNELFILE']._serialized_start=1448 - _globals['_CHANNELFILE']._serialized_end=1526 - _globals['_OEMSTORE']._serialized_start=1529 - _globals['_OEMSTORE']._serialized_end=1835 + _globals['_NODEINFOLITE']._serialized_end=948 + _globals['_DEVICESTATE']._serialized_start=951 + _globals['_DEVICESTATE']._serialized_end=1465 + _globals['_CHANNELFILE']._serialized_start=1467 + _globals['_CHANNELFILE']._serialized_end=1545 + _globals['_OEMSTORE']._serialized_start=1548 + _globals['_OEMSTORE']._serialized_end=1854 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/deviceonly_pb2.pyi b/meshtastic/protobuf/deviceonly_pb2.pyi index 747b304..11a39e2 100644 --- a/meshtastic/protobuf/deviceonly_pb2.pyi +++ b/meshtastic/protobuf/deviceonly_pb2.pyi @@ -248,11 +248,12 @@ class NodeInfoLite(google.protobuf.message.Message): device_metrics: meshtastic.protobuf.telemetry_pb2.DeviceMetrics | None = ..., channel: builtins.int = ..., via_mqtt: builtins.bool = ..., - hops_away: builtins.int = ..., + hops_away: builtins.int | None = ..., is_favorite: builtins.bool = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> 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", "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___NodeInfoLite = NodeInfoLite diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 9251717..09b9624 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xbf\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xf2\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xf3\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"s\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\x99\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xbf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xde\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xfd\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xb0\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xf3\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"s\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\xac\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x42\x0c\n\n_hops_away\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xcf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xde\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,12 +31,12 @@ if _descriptor._USE_C_DESCRIPTORS == False: _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _globals['_HARDWAREMODEL']._serialized_start=6183 - _globals['_HARDWAREMODEL']._serialized_end=7685 - _globals['_CONSTANTS']._serialized_start=7687 - _globals['_CONSTANTS']._serialized_end=7731 - _globals['_CRITICALERRORCODE']._serialized_start=7734 - _globals['_CRITICALERRORCODE']._serialized_end=8042 + _globals['_HARDWAREMODEL']._serialized_start=6280 + _globals['_HARDWAREMODEL']._serialized_end=7782 + _globals['_CONSTANTS']._serialized_start=7784 + _globals['_CONSTANTS']._serialized_end=7828 + _globals['_CRITICALERRORCODE']._serialized_start=7831 + _globals['_CRITICALERRORCODE']._serialized_end=8139 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1194 _globals['_POSITION_LOCSOURCE']._serialized_start=889 @@ -48,55 +48,55 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_ROUTEDISCOVERY']._serialized_start=1433 _globals['_ROUTEDISCOVERY']._serialized_end=1523 _globals['_ROUTING']._serialized_start=1526 - _globals['_ROUTING']._serialized_end=1973 + _globals['_ROUTING']._serialized_end=2035 _globals['_ROUTING_ERROR']._serialized_start=1720 - _globals['_ROUTING_ERROR']._serialized_end=1962 - _globals['_DATA']._serialized_start=1976 - _globals['_DATA']._serialized_end=2188 - _globals['_WAYPOINT']._serialized_start=2191 - _globals['_WAYPOINT']._serialized_end=2379 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2381 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2489 - _globals['_MESHPACKET']._serialized_start=2492 - _globals['_MESHPACKET']._serialized_end=3119 - _globals['_MESHPACKET_PRIORITY']._serialized_start=2917 - _globals['_MESHPACKET_PRIORITY']._serialized_end=3032 - _globals['_MESHPACKET_DELAYED']._serialized_start=3034 - _globals['_MESHPACKET_DELAYED']._serialized_end=3100 - _globals['_NODEINFO']._serialized_start=3122 - _globals['_NODEINFO']._serialized_end=3403 - _globals['_MYNODEINFO']._serialized_start=3405 - _globals['_MYNODEINFO']._serialized_end=3485 - _globals['_LOGRECORD']._serialized_start=3488 - _globals['_LOGRECORD']._serialized_end=3689 - _globals['_LOGRECORD_LEVEL']._serialized_start=3601 - _globals['_LOGRECORD_LEVEL']._serialized_end=3689 - _globals['_QUEUESTATUS']._serialized_start=3691 - _globals['_QUEUESTATUS']._serialized_end=3771 - _globals['_FROMRADIO']._serialized_start=3774 - _globals['_FROMRADIO']._serialized_end=4598 - _globals['_CLIENTNOTIFICATION']._serialized_start=4601 - _globals['_CLIENTNOTIFICATION']._serialized_end=4741 - _globals['_FILEINFO']._serialized_start=4743 - _globals['_FILEINFO']._serialized_end=4792 - _globals['_TORADIO']._serialized_start=4795 - _globals['_TORADIO']._serialized_end=5107 - _globals['_COMPRESSED']._serialized_start=5109 - _globals['_COMPRESSED']._serialized_end=5182 - _globals['_NEIGHBORINFO']._serialized_start=5185 - _globals['_NEIGHBORINFO']._serialized_end=5329 - _globals['_NEIGHBOR']._serialized_start=5331 - _globals['_NEIGHBOR']._serialized_end=5431 - _globals['_DEVICEMETADATA']._serialized_start=5434 - _globals['_DEVICEMETADATA']._serialized_end=5753 - _globals['_HEARTBEAT']._serialized_start=5755 - _globals['_HEARTBEAT']._serialized_end=5766 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5768 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5862 - _globals['_CHUNKEDPAYLOAD']._serialized_start=5864 - _globals['_CHUNKEDPAYLOAD']._serialized_end=5965 - _globals['_RESEND_CHUNKS']._serialized_start=5967 - _globals['_RESEND_CHUNKS']._serialized_end=5998 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=6001 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=6180 + _globals['_ROUTING_ERROR']._serialized_end=2024 + _globals['_DATA']._serialized_start=2038 + _globals['_DATA']._serialized_end=2250 + _globals['_WAYPOINT']._serialized_start=2253 + _globals['_WAYPOINT']._serialized_end=2441 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=2443 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=2551 + _globals['_MESHPACKET']._serialized_start=2554 + _globals['_MESHPACKET']._serialized_end=3181 + _globals['_MESHPACKET_PRIORITY']._serialized_start=2979 + _globals['_MESHPACKET_PRIORITY']._serialized_end=3094 + _globals['_MESHPACKET_DELAYED']._serialized_start=3096 + _globals['_MESHPACKET_DELAYED']._serialized_end=3162 + _globals['_NODEINFO']._serialized_start=3184 + _globals['_NODEINFO']._serialized_end=3484 + _globals['_MYNODEINFO']._serialized_start=3486 + _globals['_MYNODEINFO']._serialized_end=3566 + _globals['_LOGRECORD']._serialized_start=3569 + _globals['_LOGRECORD']._serialized_end=3770 + _globals['_LOGRECORD_LEVEL']._serialized_start=3682 + _globals['_LOGRECORD_LEVEL']._serialized_end=3770 + _globals['_QUEUESTATUS']._serialized_start=3772 + _globals['_QUEUESTATUS']._serialized_end=3852 + _globals['_FROMRADIO']._serialized_start=3855 + _globals['_FROMRADIO']._serialized_end=4679 + _globals['_CLIENTNOTIFICATION']._serialized_start=4682 + _globals['_CLIENTNOTIFICATION']._serialized_end=4822 + _globals['_FILEINFO']._serialized_start=4824 + _globals['_FILEINFO']._serialized_end=4873 + _globals['_TORADIO']._serialized_start=4876 + _globals['_TORADIO']._serialized_end=5188 + _globals['_COMPRESSED']._serialized_start=5190 + _globals['_COMPRESSED']._serialized_end=5263 + _globals['_NEIGHBORINFO']._serialized_start=5266 + _globals['_NEIGHBORINFO']._serialized_end=5410 + _globals['_NEIGHBOR']._serialized_start=5412 + _globals['_NEIGHBOR']._serialized_end=5512 + _globals['_DEVICEMETADATA']._serialized_start=5515 + _globals['_DEVICEMETADATA']._serialized_end=5850 + _globals['_HEARTBEAT']._serialized_start=5852 + _globals['_HEARTBEAT']._serialized_end=5863 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=5865 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=5959 + _globals['_CHUNKEDPAYLOAD']._serialized_start=5961 + _globals['_CHUNKEDPAYLOAD']._serialized_end=6062 + _globals['_RESEND_CHUNKS']._serialized_start=6064 + _globals['_RESEND_CHUNKS']._serialized_end=6095 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=6098 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=6277 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index 15c8680..b916f78 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -1389,6 +1389,14 @@ class Routing(google.protobuf.message.Message): """ The receiving node does not have a Public Key to decode with """ + ADMIN_BAD_SESSION_KEY: Routing._Error.ValueType # 36 + """ + Admin packet otherwise checks out, but uses a bogus or expired session key + """ + ADMIN_PUBLIC_KEY_UNAUTHORIZED: Routing._Error.ValueType # 37 + """ + Admin packet sent using PKC, but not from a public key on the admin key list + """ class Error(_Error, metaclass=_ErrorEnumTypeWrapper): """ @@ -1454,6 +1462,14 @@ class Routing(google.protobuf.message.Message): """ The receiving node does not have a Public Key to decode with """ + ADMIN_BAD_SESSION_KEY: Routing.Error.ValueType # 36 + """ + Admin packet otherwise checks out, but uses a bogus or expired session key + """ + ADMIN_PUBLIC_KEY_UNAUTHORIZED: Routing.Error.ValueType # 37 + """ + Admin packet sent using PKC, but not from a public key on the admin key list + """ ROUTE_REQUEST_FIELD_NUMBER: builtins.int ROUTE_REPLY_FIELD_NUMBER: builtins.int @@ -2080,11 +2096,12 @@ class NodeInfo(google.protobuf.message.Message): device_metrics: meshtastic.protobuf.telemetry_pb2.DeviceMetrics | None = ..., channel: builtins.int = ..., via_mqtt: builtins.bool = ..., - hops_away: builtins.int = ..., + hops_away: builtins.int | None = ..., is_favorite: builtins.bool = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["device_metrics", b"device_metrics", "position", b"position", "user", b"user"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> 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", "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 @@ -2695,6 +2712,7 @@ class DeviceMetadata(google.protobuf.message.Message): POSITION_FLAGS_FIELD_NUMBER: builtins.int HW_MODEL_FIELD_NUMBER: builtins.int HASREMOTEHARDWARE_FIELD_NUMBER: builtins.int + HASPKC_FIELD_NUMBER: builtins.int firmware_version: builtins.str """ Device firmware version string @@ -2735,6 +2753,10 @@ class DeviceMetadata(google.protobuf.message.Message): """ Has Remote Hardware enabled """ + hasPKC: builtins.bool + """ + Has PKC capabilities + """ def __init__( self, *, @@ -2748,8 +2770,9 @@ class DeviceMetadata(google.protobuf.message.Message): position_flags: builtins.int = ..., hw_model: global___HardwareModel.ValueType = ..., hasRemoteHardware: builtins.bool = ..., + hasPKC: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["canShutdown", b"canShutdown", "device_state_version", b"device_state_version", "firmware_version", b"firmware_version", "hasBluetooth", b"hasBluetooth", "hasEthernet", b"hasEthernet", "hasRemoteHardware", b"hasRemoteHardware", "hasWifi", b"hasWifi", "hw_model", b"hw_model", "position_flags", b"position_flags", "role", b"role"]) -> None: ... + def ClearField(self, field_name: typing.Literal["canShutdown", b"canShutdown", "device_state_version", b"device_state_version", "firmware_version", b"firmware_version", "hasBluetooth", b"hasBluetooth", "hasEthernet", b"hasEthernet", "hasPKC", b"hasPKC", "hasRemoteHardware", b"hasRemoteHardware", "hasWifi", b"hasWifi", "hw_model", b"hw_model", "position_flags", b"position_flags", "role", b"role"]) -> None: ... global___DeviceMetadata = DeviceMetadata diff --git a/protobufs b/protobufs index 0acaec6..5709c0a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 0acaec6eff00e748beeae89148093221f131cd9c +Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197 diff --git a/pyproject.toml b/pyproject.toml index 39ff255..a96101e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.5.0" +version = "2.5.1a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 9949d144a1e4ff0fb247796ba8607df9d8e850cf Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Thu, 19 Sep 2024 02:22:04 -0600 Subject: [PATCH 237/248] Enable setting and removing fixed position via remote admin --- meshtastic/__main__.py | 15 +++++---------- meshtastic/node.py | 16 +++++++++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 8eb04eb..686d207 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -286,19 +286,14 @@ def onConnected(interface): print("Connected to radio") if args.remove_position: - if args.dest != BROADCAST_ADDR: - print("Setting positions of remote nodes is not supported.") - return closeNow = True + waitForAckNak = True + print("Removing fixed position and disabling fixed position setting") - interface.localNode.removeFixedPosition() + interface.getNode(args.dest, False, **getNode_kwargs).removeFixedPosition() elif args.setlat or args.setlon or args.setalt: - if args.dest != BROADCAST_ADDR: - print( - "Setting latitude, longitude, and altitude of remote nodes is not supported." - ) - return closeNow = True + waitForAckNak = True alt = 0 lat = 0 @@ -321,7 +316,7 @@ def onConnected(interface): print("Setting device position and enabling fixed position setting") # can include lat/long/alt etc: latitude = 37.5, longitude = -122.1 - interface.localNode.setFixedPosition(lat, lon, alt) + interface.getNode(args.dest, False, **getNode_kwargs).setFixedPosition(lat, lon, alt) if args.set_owner or args.set_owner_short: closeNow = True diff --git a/meshtastic/node.py b/meshtastic/node.py index 278ea8a..bef632e 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -685,9 +685,6 @@ class Node: def setFixedPosition(self, lat: Union[int, float], lon: Union[int, float], alt: int): """Tell the node to set fixed position to the provided value and enable the fixed position setting""" self.ensureSessionKey() - if self != self.iface.localNode: - logging.error("Setting position of remote nodes is not supported.") - return None p = mesh_pb2.Position() if isinstance(lat, float) and lat != 0.0: @@ -705,7 +702,12 @@ class Node: a = admin_pb2.AdminMessage() a.set_fixed_position.CopyFrom(p) - return self._sendAdmin(a) + + if self == self.iface.localNode: + onResponse = None + else: + onResponse = self.onAckNak + return self._sendAdmin(a, onResponse=onResponse) def removeFixedPosition(self): """Tell the node to remove the fixed position and set the fixed position setting to false""" @@ -714,7 +716,11 @@ class Node: p.remove_fixed_position = True logging.info(f"Telling node to remove fixed position") - return self._sendAdmin(p) + if self == self.iface.localNode: + onResponse = None + else: + onResponse = self.onAckNak + return self._sendAdmin(p, onResponse=onResponse) def _fixupChannels(self): """Fixup indexes and add disabled channels as needed""" From 40353a387e1782c4bcc7a882a3800ca52d4b30d3 Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Thu, 19 Sep 2024 03:31:01 -0600 Subject: [PATCH 238/248] Fix tests for remote position configs --- meshtastic/tests/test_main.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 6f2dd26..6fe5c67 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -726,8 +726,8 @@ def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_ @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") -def test_main_removeposition_invalid(capsys): - """Test --remove-position with an invalid dest""" +def test_main_removeposition_remote(capsys): + """Test --remove-position with a remote dest""" sys.argv = ["", "--remove-position", "--dest", "!12345678"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) @@ -735,14 +735,15 @@ def test_main_removeposition_invalid(capsys): main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) - assert re.search(r"remote nodes is not supported", out, re.MULTILINE) + assert re.search(r"Removing fixed position and disabling fixed position setting", out, re.MULTILINE) + assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE) assert err == "" mo.assert_called() @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") -def test_main_setlat_invalid(capsys): - """Test --setlat with an invalid dest""" +def test_main_setlat_remote(capsys): + """Test --setlat with a remote dest""" sys.argv = ["", "--setlat", "37.5", "--dest", "!12345678"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) @@ -750,7 +751,8 @@ def test_main_setlat_invalid(capsys): main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) - assert re.search(r"remote nodes is not supported", out, re.MULTILINE) + assert re.search(r"Setting device position and enabling fixed position setting", out, re.MULTILINE) + assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE) assert err == "" mo.assert_called() @@ -769,7 +771,7 @@ def test_main_removeposition(capsys): mocked_node.removeFixedPosition.side_effect = mock_removeFixedPosition iface = MagicMock(autospec=SerialInterface) - iface.localNode = mocked_node + iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() @@ -796,7 +798,7 @@ def test_main_setlat(capsys): mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) - iface.localNode = mocked_node + iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() @@ -825,7 +827,7 @@ def test_main_setlon(capsys): mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) - iface.localNode = mocked_node + iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() @@ -854,7 +856,7 @@ def test_main_setalt(capsys): mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) - iface.localNode = mocked_node + iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() From 40019a9712f7d87a0d58dca9ea4856a961293f57 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 22 Sep 2024 09:32:04 -0700 Subject: [PATCH 239/248] Add a --set-time command that set's the node time using a provided timestamp or the host system clock. --- meshtastic/__main__.py | 13 +++++++++++++ meshtastic/node.py | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 686d207..ccac5b2 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -285,6 +285,9 @@ def onConnected(interface): if not args.export_config: print("Connected to radio") + if args.set_time is not None: + interface.getNode(args.dest, False, **getNode_kwargs).setTime(args.set_time) + if args.remove_position: closeNow = True waitForAckNak = True @@ -1597,6 +1600,16 @@ def initParser(): action="store_true", ) + group.add_argument( + "--set-time", + help="Set the time to the provided unix epoch timestamp, or the system's current time if omitted or 0.", + action="store", + type=int, + nargs="?", + default=None, + const=0, + ) + group.add_argument( "--reply", help="Reply to received messages", action="store_true" ) diff --git a/meshtastic/node.py b/meshtastic/node.py index bef632e..91cc3a9 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -722,6 +722,21 @@ class Node: onResponse = self.onAckNak return self._sendAdmin(p, onResponse=onResponse) + def setTime(self, timeSec: int = 0): + """Tell the node to set its time to the provided timestamp, or the system's current time if not provided or 0.""" + self.ensureSessionKey() + if timeSec == 0: + timeSec = int(time.time()) + p = admin_pb2.AdminMessage() + p.set_time_only = timeSec + logging.info(f"Setting node time to {timeSec}") + + if self == self.iface.localNode: + onResponse = None + else: + onResponse = self.onAckNak + return self._sendAdmin(p, onResponse=onResponse) + def _fixupChannels(self): """Fixup indexes and add disabled channels as needed""" From 27729995d287392e48a89beaf6f6e79314edd97a Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 28 Sep 2024 11:13:04 -0700 Subject: [PATCH 240/248] Default to pkiEncrypted always on for admin messages --- meshtastic/mesh_interface.py | 14 ++++++++++++-- meshtastic/node.py | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 872c7f0..b4d2a53 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -394,6 +394,8 @@ class MeshInterface: # pylint: disable=R0902 onResponseAckPermitted: bool=False, channelIndex: int=0, hopLimit: Optional[int]=None, + pkiEncrypted: Optional[bool]=False, + publicKey: Optional[bytes]=None, ): """Send a data packet to some other node @@ -449,7 +451,7 @@ class MeshInterface: # pylint: disable=R0902 if onResponse is not None: 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) + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit, pkiEncrypted=pkiEncrypted, publicKey=publicKey) return p def sendPosition( @@ -689,7 +691,9 @@ class MeshInterface: # pylint: disable=R0902 meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False, - hopLimit: Optional[int]=None + hopLimit: Optional[int]=None, + pkiEncrypted: Optional[bool]=False, + publicKey: Optional[bytes]=None, ): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. @@ -738,6 +742,12 @@ class MeshInterface: # pylint: disable=R0902 loraConfig = getattr(self.localNode.localConfig, "lora") meshPacket.hop_limit = getattr(loraConfig, "hop_limit") + if pkiEncrypted: + meshPacket.pki_encrypted = True + + if publicKey is not None: + meshPacket.public_key = publicKey + # if the user hasn't set an ID for this packet (likely and recommended), # we should pick a new unique ID so the message can be tracked. if meshPacket.id == 0: diff --git a/meshtastic/node.py b/meshtastic/node.py index 91cc3a9..2986ded 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -894,6 +894,7 @@ class Node: wantResponse=wantResponse, onResponse=onResponse, channelIndex=adminIndex, + pkiEncrypted=True, ) def ensureSessionKey(self): From 81db38956b44aa6986f7185a7c35feed43b5cc5d Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 28 Sep 2024 18:37:05 -0700 Subject: [PATCH 241/248] Silence pylint --- meshtastic/mesh_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index b4d2a53..a70a0db 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -396,7 +396,7 @@ class MeshInterface: # pylint: disable=R0902 hopLimit: Optional[int]=None, pkiEncrypted: Optional[bool]=False, publicKey: Optional[bytes]=None, - ): + ): # pylint: disable=R0913 """Send a data packet to some other node Keyword Arguments: From bbd6d6a5414417d702437ed7091f927f6ff82933 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 28 Sep 2024 20:11:52 -0700 Subject: [PATCH 242/248] Change order of logging and parsing fromRadioBytes, and add a bit more traceback logging at that point --- meshtastic/mesh_interface.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index a70a0db..b0dca56 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -8,6 +8,7 @@ import random import sys import threading import time +import traceback from datetime import datetime from decimal import Decimal from typing import Any, Callable, Dict, List, Optional, Union @@ -1023,10 +1024,17 @@ class MeshInterface: # pylint: disable=R0902 Called by subclasses.""" fromRadio = mesh_pb2.FromRadio() - fromRadio.ParseFromString(fromRadioBytes) logging.debug( f"in mesh_interface.py _handleFromRadio() fromRadioBytes: {fromRadioBytes}" ) + try: + fromRadio.ParseFromString(fromRadioBytes) + except Exception as ex: + logging.error( + f"Error while parsing FromRadio bytes:{fromRadioBytes} {ex}" + ) + traceback.print_exc() + raise ex asDict = google.protobuf.json_format.MessageToDict(fromRadio) logging.debug(f"Received from radio: {fromRadio}") if fromRadio.HasField("my_info"): From cbd3c119feeb82db3c6b6dcddab973ff6aaa58e0 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sat, 28 Sep 2024 20:15:08 -0700 Subject: [PATCH 243/248] Fix pylint errors --- meshtastic/mesh_interface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index b0dca56..ba20e29 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -140,13 +140,13 @@ class MeshInterface: # pylint: disable=R0902 def __enter__(self): return self - def __exit__(self, exc_type, exc_value, traceback): + def __exit__(self, exc_type, exc_value, trace): if exc_type is not None and exc_value is not None: logging.error( f"An exception of type {exc_type} with value {exc_value} has occurred" ) - if traceback is not None: - logging.error(f"Traceback: {traceback}") + if trace is not None: + logging.error(f"Traceback: {trace}") self.close() @staticmethod From 3fb1e67357833c56b2b1c9d23f2d8f5076abff90 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 29 Sep 2024 21:30:36 +0000 Subject: [PATCH 244/248] bump version to 2.5.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a96101e..d26c577 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.5.1a0" +version = "2.5.1" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From 65305af1840f720eb6e3f7aa0772aa0dd6f8c27e Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Sun, 29 Sep 2024 14:34:53 -0700 Subject: [PATCH 245/248] protobufs/alpha version: 2.5.2 --- meshtastic/protobuf/mesh_pb2.py | 12 ++++++------ meshtastic/protobuf/mesh_pb2.pyi | 24 ++++++++++++++++++++---- protobufs | 2 +- pyproject.toml | 2 +- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 09b9624..a8cf521 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xfd\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xb0\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xf3\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"s\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\xac\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x42\x0c\n\n_hops_away\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xcf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xde\x0b\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xea\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xfd\x03\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xb0\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xf3\x04\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\"s\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\x42\x11\n\x0fpayload_variant\"\xac\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\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\x42\x0c\n\n_hops_away\"P\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xb8\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x42\x11\n\x0fpayload_variant\"\x8c\x01\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\tB\x0b\n\t_reply_id\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xcf\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\"\x0b\n\tHeartbeat\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x9d\x0c\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x1a\n\x16HELTEC_WIRELESS_BRIDGE\x10\x18\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\r\n\tRPI_PICO2\x10O\x12\x12\n\x0eM5STACK_CORES3\x10P\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xed\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\rB_\n\x13\x63om.geeksville.meshB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,11 +32,11 @@ if _descriptor._USE_C_DESCRIPTORS == False: _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' _globals['_HARDWAREMODEL']._serialized_start=6280 - _globals['_HARDWAREMODEL']._serialized_end=7782 - _globals['_CONSTANTS']._serialized_start=7784 - _globals['_CONSTANTS']._serialized_end=7828 - _globals['_CRITICALERRORCODE']._serialized_start=7831 - _globals['_CRITICALERRORCODE']._serialized_end=8139 + _globals['_HARDWAREMODEL']._serialized_end=7845 + _globals['_CONSTANTS']._serialized_start=7847 + _globals['_CONSTANTS']._serialized_end=7891 + _globals['_CRITICALERRORCODE']._serialized_start=7894 + _globals['_CRITICALERRORCODE']._serialized_end=8202 _globals['_POSITION']._serialized_start=273 _globals['_POSITION']._serialized_end=1194 _globals['_POSITION_LOCSOURCE']._serialized_start=889 diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index b916f78..74d9aac 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -129,6 +129,10 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ Heltec HRU-3601: https://heltec.org/project/hru-3601/ """ + HELTEC_WIRELESS_BRIDGE: _HardwareModel.ValueType # 24 + """ + Heltec Wireless Bridge + """ STATION_G1: _HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -201,7 +205,7 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ M5STACK: _HardwareModel.ValueType # 42 """ - M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ + M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ """ HELTEC_V3: _HardwareModel.ValueType # 43 """ @@ -359,8 +363,12 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ ^^^ short A0 to switch to I2C address 0x3C """ M5STACK_COREBASIC: _HardwareModel.ValueType # 77 - """M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/""" + """M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/""" M5STACK_CORE2: _HardwareModel.ValueType # 78 + RPI_PICO2: _HardwareModel.ValueType # 79 + """Pico2 with Waveshare Hat, same as Pico""" + M5STACK_CORES3: _HardwareModel.ValueType # 80 + """M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/""" PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -474,6 +482,10 @@ HELTEC_HRU_3601: HardwareModel.ValueType # 23 """ Heltec HRU-3601: https://heltec.org/project/hru-3601/ """ +HELTEC_WIRELESS_BRIDGE: HardwareModel.ValueType # 24 +""" +Heltec Wireless Bridge +""" STATION_G1: HardwareModel.ValueType # 25 """ B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station @@ -546,7 +558,7 @@ Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio """ M5STACK: HardwareModel.ValueType # 42 """ -M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ +M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ """ HELTEC_V3: HardwareModel.ValueType # 43 """ @@ -704,8 +716,12 @@ https://www.adafruit.com/product/938 ^^^ short A0 to switch to I2C address 0x3C """ M5STACK_COREBASIC: HardwareModel.ValueType # 77 -"""M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/""" +"""M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/""" M5STACK_CORE2: HardwareModel.ValueType # 78 +RPI_PICO2: HardwareModel.ValueType # 79 +"""Pico2 with Waveshare Hat, same as Pico""" +M5STACK_CORES3: HardwareModel.ValueType # 80 +"""M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/protobufs b/protobufs index 5709c0a..9651aa5 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197 +Subproject commit 9651aa59eaa3b54d801b9c251efcfe842790db32 diff --git a/pyproject.toml b/pyproject.toml index d26c577..83dd690 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.5.1" +version = "2.5.2a0" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" From b73cc1f4992d029b1ad6cd940e519beb5eff500f Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 1 Oct 2024 14:00:06 -0700 Subject: [PATCH 246/248] Make it so wantconfig isn't a 1 in 4294967296 lottery for getting no nodes --- meshtastic/mesh_interface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index ba20e29..db057a3 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -914,6 +914,8 @@ class MeshInterface: # pylint: disable=R0902 startConfig = mesh_pb2.ToRadio() if self.configId is None or not self.noNodes: self.configId = random.randint(0, 0xFFFFFFFF) + if self.configId == NODELESS_WANT_CONFIG_ID: + self.configId = self.configId + 1 startConfig.want_config_id = self.configId self._sendToRadio(startConfig) From 6be39695778473039dc1cd36503ae2653df817a9 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Tue, 1 Oct 2024 18:10:14 -0700 Subject: [PATCH 247/248] Add a number of argument groups to organize the help output --- meshtastic/__main__.py | 683 +++++++++++++++++++++++------------------ 1 file changed, 387 insertions(+), 296 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index ccac5b2..b908eec 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1228,7 +1228,7 @@ def common(): def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: - """Add connection specifiation arguments""" + """Add connection specification arguments""" outer = parser.add_argument_group( "Connection", @@ -1264,96 +1264,61 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse const="any", ) + outer.add_argument( + "--ble-scan", + help="Scan for Meshtastic BLE devices that may be available to connect to", + action="store_true", + ) + return parser - -def initParser(): - """Initialize the command line argument parsing.""" - parser = mt_config.parser - args = mt_config.args - - # The "Help" group includes the help option and other informational stuff about the CLI itself - outerHelpGroup = parser.add_argument_group("Help") - helpGroup = outerHelpGroup.add_mutually_exclusive_group() - helpGroup.add_argument( - "-h", "--help", action="help", help="show this help message and exit" +def addSelectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add node/channel specification arguments""" + group = parser.add_argument_group( + "Selection", + "Arguments that select channels to use, destination nodes, etc." ) - the_version = get_active_version() - helpGroup.add_argument("--version", action="version", version=f"{the_version}") - - helpGroup.add_argument( - "--support", - action="store_true", - help="Show support info (useful when troubleshooting an issue)", + group.add_argument( + "--dest", + help="The destination node id for any sent commands, if not set '^all' or '^local' is assumed as appropriate", + default=None, + metavar="!xxxxxxxx", ) - # Connection arguments to indicate a device to connect to - parser = addConnectionArgs(parser) + group.add_argument( + "--ch-index", + help="Set the specified channel index for channel-specific commands. Channels start at 0 (0 is the PRIMARY channel).", + action="store", + ) - # Arguments concerning viewing and setting configuration + return parser - # Arguments for sending or requesting things from the local device +def addImportExportArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add import/export config arguments""" + group = parser.add_argument_group( + "Import/Export", + "Arguments that concern importing and exporting configuration of Meshtastic devices", + ) - # Arguments for sending or requesting things from the mesh - - # All the rest of the arguments - group = parser.add_argument_group("optional arguments") group.add_argument( "--configure", help="Specify a path to a yaml(.yml) file containing the desired settings for the connected device.", action="append", ) - group.add_argument( "--export-config", help="Export the configuration in yaml(.yml) format.", action="store_true", ) + return parser - group.add_argument( - "--seriallog", - help="Log device serial output to either 'none' or a filename to append to. Defaults to 'stdout' if no filename specified.", - nargs="?", - const="stdout", - default=None, - ) +def addConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments to do with configuring a device""" - group.add_argument( - "--info", - help="Read and display the radio config information", - action="store_true", - ) - - group.add_argument( - "--get-canned-message", - help="Show the canned message plugin message", - action="store_true", - ) - - group.add_argument( - "--get-ringtone", help="Show the stored ringtone", action="store_true" - ) - - group.add_argument( - "--nodes", - help="Print Node List in a pretty formatted table", - action="store_true", - ) - - group.add_argument( - "--qr", - help=( - "Display a QR code for the node's primary channel (or all channels with --qr-all). " - "Also shows the shareable channel URL." - ), - action="store_true", - ) - - group.add_argument( - "--qr-all", - help="Display a QR code and URL for all of the node's channels.", - action="store_true", + group = parser.add_argument_group( + "Configuration", + "Arguments that concern general configuration of Meshtastic devices", ) group.add_argument( @@ -1373,14 +1338,104 @@ def initParser(): action="append", ) - group.add_argument("--seturl", help="Set a channel URL", action="store") + group.add_argument( + "--begin-edit", + help="Tell the node to open a transaction to edit settings", + action="store_true", + ) group.add_argument( - "--ch-index", - help="Set the specified channel index. Channels start at 0 (0 is the PRIMARY channel).", + "--commit-edit", + help="Tell the node to commit open settings transaction", + action="store_true", + ) + + group.add_argument( + "--get-canned-message", + help="Show the canned message plugin message", + action="store_true", + ) + + group.add_argument( + "--set-canned-message", + help="Set the canned messages plugin message (up to 200 characters).", action="store", ) + group.add_argument( + "--get-ringtone", help="Show the stored ringtone", action="store_true" + ) + + group.add_argument( + "--set-ringtone", + help="Set the Notification Ringtone (up to 230 characters).", + action="store", + ) + + group.add_argument( + "--ch-vlongslow", + help="Change to the very long-range and slow modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-longslow", + help="Change to the long-range and slow modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-longfast", + help="Change to the long-range and fast modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-medslow", + help="Change to the med-range and slow modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-medfast", + help="Change to the med-range and fast modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-shortslow", + help="Change to the short-range and slow modem preset", + action="store_true", + ) + + group.add_argument( + "--ch-shortfast", + help="Change to the short-range and fast modem preset", + action="store_true", + ) + + group.add_argument("--set-owner", help="Set device owner name", action="store") + + group.add_argument( + "--set-owner-short", help="Set device owner short name", action="store" + ) + + group.add_argument( + "--set-ham", help="Set licensed Ham ID and turn off encryption", action="store" + ) + + group.add_argument("--seturl", help="Set a channel URL", action="store") + + return parser + +def addChannelConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments to do with configuring channels""" + + group = parser.add_argument_group( + "Channel Configuration", + "Arguments that concern configuration of channels", + ) + group.add_argument( "--ch-add", help="Add a secondary channel, you must specify a channel name", @@ -1391,23 +1446,6 @@ def initParser(): "--ch-del", help="Delete the ch-index channel", action="store_true" ) - group.add_argument( - "--ch-enable", - help="Enable the specified channel", - action="store_true", - dest="ch_enable", - default=False, - ) - - # Note: We are doing a double negative here (Do we want to disable? If ch_disable==True, then disable.) - group.add_argument( - "--ch-disable", - help="Disable the specified channel", - action="store_true", - dest="ch_disable", - default=False, - ) - group.add_argument( "--ch-set", help=( @@ -1423,210 +1461,52 @@ def initParser(): group.add_argument( "--channel-fetch-attempts", - help=("Attempt to retrieve channel settings for --ch-set this many times before giving up."), + help=("Attempt to retrieve channel settings for --ch-set this many times before giving up. Default %(default)s."), default=3, type=int, ) group.add_argument( - "--timeout", - help="How long to wait for replies", - default=300, - type=int, - ) - - group.add_argument( - "--ch-vlongslow", - help="Change to the very long-range and slow channel", + "--qr", + help=( + "Display a QR code for the node's primary channel (or all channels with --qr-all). " + "Also shows the shareable channel URL." + ), action="store_true", ) group.add_argument( - "--ch-longslow", - help="Change to the long-range and slow channel", + "--qr-all", + help="Display a QR code and URL for all of the node's channels.", action="store_true", ) group.add_argument( - "--ch-longfast", - help="Change to the long-range and fast channel", + "--ch-enable", + help="Enable the specified channel. Use --ch-add instead whenever possible.", action="store_true", + dest="ch_enable", + default=False, ) + # Note: We are doing a double negative here (Do we want to disable? If ch_disable==True, then disable.) group.add_argument( - "--ch-medslow", - help="Change to the med-range and slow channel", + "--ch-disable", + help="Disable the specified channel Use --ch-del instead whenever possible.", action="store_true", + dest="ch_disable", + default=False, ) - group.add_argument( - "--ch-medfast", - help="Change to the med-range and fast channel", - action="store_true", - ) + return parser - group.add_argument( - "--ch-shortslow", - help="Change to the short-range and slow channel", - action="store_true", - ) +def addPositionConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments to do with fixed positions and position config""" - group.add_argument( - "--ch-shortfast", - help="Change to the short-range and fast channel", - action="store_true", + group = parser.add_argument_group( + "Position Configuration", + "Arguments that modify fixed position and other position-related configuration.", ) - - group.add_argument("--set-owner", help="Set device owner name", action="store") - - group.add_argument( - "--set-owner-short", help="Set device owner short name", action="store" - ) - - group.add_argument( - "--set-canned-message", - help="Set the canned messages plugin message (up to 200 characters).", - action="store", - ) - - group.add_argument( - "--set-ringtone", - help="Set the Notification Ringtone (up to 230 characters).", - action="store", - ) - - group.add_argument( - "--set-ham", help="Set licensed Ham ID and turn off encryption", action="store" - ) - - group.add_argument( - "--dest", - help="The destination node id for any sent commands, if not set '^all' or '^local' is assumed as appropriate", - default=None, - ) - - group.add_argument( - "--sendtext", - help="Send a text message. Can specify a destination '--dest' and/or channel index '--ch-index'.", - ) - - group.add_argument( - "--traceroute", - help="Traceroute from connected node to a destination. " - "You need pass the destination ID as argument, like " - "this: '--traceroute !ba4bf9d0' " - "Only nodes that have the encryption key can be traced.", - ) - - group.add_argument( - "--request-telemetry", - help="Request telemetry from a node. " - "You need to pass the destination ID as argument with '--dest'. " - "For repeaters, the nodeNum is required.", - action="store_true", - ) - - group.add_argument( - "--request-position", - help="Request the position from a node. " - "You need to pass the destination ID as an argument with '--dest'. " - "For repeaters, the nodeNum is required.", - action="store_true", - ) - - group.add_argument( - "--ack", - help="Use in combination with --sendtext to wait for an acknowledgment.", - action="store_true", - ) - - group.add_argument( - "--reboot", help="Tell the destination node to reboot", action="store_true" - ) - - group.add_argument( - "--reboot-ota", - help="Tell the destination node to reboot into factory firmware (ESP32)", - action="store_true", - ) - - group.add_argument( - "--enter-dfu", - help="Tell the destination node to enter DFU mode (NRF52)", - action="store_true", - ) - - group.add_argument( - "--shutdown", help="Tell the destination node to shutdown", action="store_true" - ) - - group.add_argument( - "--device-metadata", - help="Get the device metadata from the node", - action="store_true", - ) - - group.add_argument( - "--begin-edit", - help="Tell the node to open a transaction to edit settings", - action="store_true", - ) - - group.add_argument( - "--commit-edit", - help="Tell the node to commit open settings transaction", - action="store_true", - ) - - group.add_argument( - "--factory-reset", "--factory-reset-config", - help="Tell the destination node to install the default config, preserving BLE bonds & PKI keys", - action="store_true", - ) - - group.add_argument( - "--factory-reset-device", - help="Tell the destination node to install the default config and clear BLE bonds & PKI keys", - action="store_true", - ) - - group.add_argument( - "--remove-node", - help="Tell the destination node to remove a specific node from its DB, by node number or ID", - ) - group.add_argument( - "--reset-nodedb", - help="Tell the destination node to clear its list of nodes", - action="store_true", - ) - - group.add_argument( - "--set-time", - help="Set the time to the provided unix epoch timestamp, or the system's current time if omitted or 0.", - action="store", - type=int, - nargs="?", - default=None, - const=0, - ) - - group.add_argument( - "--reply", help="Reply to received messages", action="store_true" - ) - - group.add_argument( - "--no-time", - help="Deprecated. Retained for backwards compatibility in scripts, but is a no-op.", - action="store_true", - ) - - group.add_argument( - "--no-nodes", - help="Request that the node not send node info to the client. " - "Will break things that depend on the nodedb, but will speed up startup. Requires 2.3.11+ firmware.", - action="store_true", - ) - group.add_argument( "--setalt", help="Set device altitude in meters (allows use without GPS), and enable fixed position. " @@ -1659,6 +1539,215 @@ def initParser(): nargs="*", action="store", ) + return parser + +def addLocalActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments concerning local-only information & actions""" + group = parser.add_argument_group( + "Local Actions", + "Arguments that take actions or request information from the local node only.", + ) + + group.add_argument( + "--info", + help="Read and display the radio config information", + action="store_true", + ) + + group.add_argument( + "--nodes", + help="Print Node List in a pretty formatted table", + action="store_true", + ) + + return parser + +def addRemoteActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments concerning information & actions that may interact with the mesh""" + group = parser.add_argument_group( + "Remote Actions", + "Arguments that take actions or request information from either the local node or remote nodes via the mesh.", + ) + + group.add_argument( + "--sendtext", + help="Send a text message. Can specify a destination '--dest' and/or channel index '--ch-index'.", + ) + + group.add_argument( + "--traceroute", + help="Traceroute from connected node to a destination. " + "You need pass the destination ID as argument, like " + "this: '--traceroute !ba4bf9d0' " + "Only nodes that have the encryption key can be traced.", + ) + + group.add_argument( + "--request-telemetry", + help="Request telemetry from a node. " + "You need to pass the destination ID as argument with '--dest'. " + "For repeaters, the nodeNum is required.", + action="store_true", + ) + + group.add_argument( + "--request-position", + help="Request the position from a node. " + "You need to pass the destination ID as an argument with '--dest'. " + "For repeaters, the nodeNum is required.", + action="store_true", + ) + + group.add_argument( + "--reply", help="Reply to received messages", action="store_true" + ) + + return parser + +def addRemoteAdminArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: + """Add arguments concerning admin actions that may interact with the mesh""" + + outer = parser.add_argument_group( + "Remote Admin Actions", + "Arguments that interact with local node or remote nodes via the mesh, requiring admin access.", + ) + + group = outer.add_mutually_exclusive_group() + + group.add_argument( + "--reboot", help="Tell the destination node to reboot", action="store_true" + ) + + group.add_argument( + "--reboot-ota", + help="Tell the destination node to reboot into factory firmware (ESP32)", + action="store_true", + ) + + group.add_argument( + "--enter-dfu", + help="Tell the destination node to enter DFU mode (NRF52)", + action="store_true", + ) + + group.add_argument( + "--shutdown", help="Tell the destination node to shutdown", action="store_true" + ) + + group.add_argument( + "--device-metadata", + help="Get the device metadata from the node", + action="store_true", + ) + + group.add_argument( + "--factory-reset", "--factory-reset-config", + help="Tell the destination node to install the default config, preserving BLE bonds & PKI keys", + action="store_true", + ) + + group.add_argument( + "--factory-reset-device", + help="Tell the destination node to install the default config and clear BLE bonds & PKI keys", + action="store_true", + ) + + group.add_argument( + "--remove-node", + help="Tell the destination node to remove a specific node from its DB, by node number or ID", + metavar="!xxxxxxxx" + ) + group.add_argument( + "--reset-nodedb", + help="Tell the destination node to clear its list of nodes", + action="store_true", + ) + + group.add_argument( + "--set-time", + help="Set the time to the provided unix epoch timestamp, or the system's current time if omitted or 0.", + action="store", + type=int, + nargs="?", + default=None, + const=0, + metavar="TIMESTAMP", + ) + + return parser + +def initParser(): + """Initialize the command line argument parsing.""" + parser = mt_config.parser + args = mt_config.args + + # The "Help" group includes the help option and other informational stuff about the CLI itself + outerHelpGroup = parser.add_argument_group("Help") + helpGroup = outerHelpGroup.add_mutually_exclusive_group() + helpGroup.add_argument( + "-h", "--help", action="help", help="show this help message and exit" + ) + + the_version = get_active_version() + helpGroup.add_argument("--version", action="version", version=f"{the_version}") + + helpGroup.add_argument( + "--support", + action="store_true", + help="Show support info (useful when troubleshooting an issue)", + ) + + # Connection arguments to indicate a device to connect to + parser = addConnectionArgs(parser) + + # Selection arguments to denote nodes and channels to use + parser = addSelectionArgs(parser) + + # Arguments concerning viewing and setting configuration + parser = addImportExportArgs(parser) + parser = addConfigArgs(parser) + parser = addPositionConfigArgs(parser) + parser = addChannelConfigArgs(parser) + + # Arguments for sending or requesting things from the local device + parser = addLocalActionArgs(parser) + + # Arguments for sending or requesting things from the mesh + parser = addRemoteActionArgs(parser) + parser = addRemoteAdminArgs(parser) + + # All the rest of the arguments + group = parser.add_argument_group("Miscellaneous arguments") + + group.add_argument( + "--seriallog", + help="Log device serial output to either 'none' or a filename to append to. Defaults to '%(const)s' if no filename specified.", + nargs="?", + const="stdout", + default=None, + metavar="LOG_DESTINATION", + ) + + group.add_argument( + "--ack", + help="Use in combination with compatible actions (e.g. --sendtext) to wait for an acknowledgment.", + action="store_true", + ) + + group.add_argument( + "--timeout", + help="How long to wait for replies. Default %(default)ss.", + default=300, + type=int, + metavar="SECONDS", + ) + + group.add_argument( + "--no-nodes", + help="Request that the node not send node info to the client. " + "Will break things that depend on the nodedb, but will speed up startup. Requires 2.3.11+ firmware.", + action="store_true", + ) group.add_argument( "--debug", help="Show API library debug log messages", action="store_true" @@ -1670,6 +1759,33 @@ def initParser(): action="store_true", ) + group.add_argument( + "--wait-to-disconnect", + help="How many seconds to wait before disconnecting from the device.", + const="5", + nargs="?", + action="store", + metavar="SECONDS", + ) + + group.add_argument( + "--noproto", + help="Don't start the API, just function as a dumb serial terminal.", + action="store_true", + ) + + group.add_argument( + "--listen", + help="Just stay open and listen to the protobuf stream. Enables debug logging.", + action="store_true", + ) + + group.add_argument( + "--no-time", + help="Deprecated. Retained for backwards compatibility in scripts, but is a no-op.", + action="store_true", + ) + power_group = parser.add_argument_group( "Power Testing", "Options for power testing/logging." ) @@ -1724,31 +1840,6 @@ def initParser(): const="default", ) - group.add_argument( - "--ble-scan", - help="Scan for Meshtastic BLE devices", - action="store_true", - ) - - group.add_argument( - "--wait-to-disconnect", - help="How many seconds to wait before disconnecting from the device.", - const="5", - nargs="?", - action="store", - ) - - group.add_argument( - "--noproto", - help="Don't start the API, just function as a dumb serial terminal.", - action="store_true", - ) - - group.add_argument( - "--listen", - help="Just stay open and listen to the protobuf stream. Enables debug logging.", - action="store_true", - ) remoteHardwareArgs = parser.add_argument_group( "Remote Hardware", "Arguments related to the Remote Hardware module" From 915066e0af59fd58e2f88c5bd83395acfac1da13 Mon Sep 17 00:00:00 2001 From: Ian McEwen Date: Thu, 3 Oct 2024 19:45:03 -0700 Subject: [PATCH 248/248] add metavars for a bunch of arguments for nicer docs --- meshtastic/__main__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index b908eec..f34595c 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1290,6 +1290,7 @@ def addSelectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser "--ch-index", help="Set the specified channel index for channel-specific commands. Channels start at 0 (0 is the PRIMARY channel).", action="store", + metavar="INDEX", ) return parser @@ -1329,6 +1330,7 @@ def addConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: ), nargs=1, action="append", + metavar="FIELD" ) group.add_argument( @@ -1336,6 +1338,7 @@ def addConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: help="Set a preferences field. Can use either snake_case or camelCase format. (ex: 'ls_secs' or 'lsSecs')", nargs=2, action="append", + metavar=("FIELD", "VALUE"), ) group.add_argument( @@ -1370,6 +1373,7 @@ def addConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: "--set-ringtone", help="Set the Notification Ringtone (up to 230 characters).", action="store", + metavar="RINGTONE", ) group.add_argument( @@ -1457,6 +1461,7 @@ def addChannelConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ), nargs=2, action="append", + metavar=("FIELD", "VALUE"), ) group.add_argument( @@ -1464,6 +1469,7 @@ def addChannelConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPa help=("Attempt to retrieve channel settings for --ch-set this many times before giving up. Default %(default)s."), default=3, type=int, + metavar="ATTEMPTS", ) group.add_argument( @@ -1572,6 +1578,7 @@ def addRemoteActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPar group.add_argument( "--sendtext", help="Send a text message. Can specify a destination '--dest' and/or channel index '--ch-index'.", + metavar="TEXT", ) group.add_argument( @@ -1579,7 +1586,8 @@ def addRemoteActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPar help="Traceroute from connected node to a destination. " "You need pass the destination ID as argument, like " "this: '--traceroute !ba4bf9d0' " - "Only nodes that have the encryption key can be traced.", + "Only nodes with a shared channel can be traced.", + metavar="!xxxxxxxx", ) group.add_argument(