mirror of
https://github.com/meshtastic/python.git
synced 2025-12-26 01:17:51 -05:00
Compare commits
171 Commits
2.3.3
...
ble-loggin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c2851db85 | ||
|
|
7e440693a3 | ||
|
|
18c2d08bf0 | ||
|
|
a3afc2ae0a | ||
|
|
f6d1b4bc39 | ||
|
|
9004f1ed57 | ||
|
|
bd767af485 | ||
|
|
6194e41baf | ||
|
|
532ca54ba4 | ||
|
|
898018ebf3 | ||
|
|
9f015f499a | ||
|
|
dc50a60b01 | ||
|
|
a24384cbe2 | ||
|
|
adbfb328b2 | ||
|
|
6df89f54a7 | ||
|
|
897adfb8c2 | ||
|
|
62ce8eaa77 | ||
|
|
3e8a807868 | ||
|
|
6d846c3a63 | ||
|
|
88b73611f0 | ||
|
|
f5febc566f | ||
|
|
c3dcafb5ef | ||
|
|
96afa703ba | ||
|
|
0b9af0dcba | ||
|
|
1b14b1ef20 | ||
|
|
68836b1af1 | ||
|
|
195f0c9d90 | ||
|
|
1ff7334385 | ||
|
|
b15e27c7b6 | ||
|
|
267923fdc5 | ||
|
|
9ab1b32bdb | ||
|
|
3a4795d3b8 | ||
|
|
c2a2d5a77c | ||
|
|
b30cde979c | ||
|
|
8456f36c6b | ||
|
|
81266e756b | ||
|
|
62f16d34d4 | ||
|
|
e6a88e055f | ||
|
|
7bea6f6120 | ||
|
|
725de4c2f9 | ||
|
|
4203553a44 | ||
|
|
9e319f3c52 | ||
|
|
cd5913ae6d | ||
|
|
ccfb04720f | ||
|
|
c34d08b0e5 | ||
|
|
b5d1b7612f | ||
|
|
b58094b9ce | ||
|
|
23f41bff0a | ||
|
|
a1021c4f78 | ||
|
|
b06329f47e | ||
|
|
53b0e35b0c | ||
|
|
9ac5aeeaf0 | ||
|
|
5c703aff1d | ||
|
|
5441266565 | ||
|
|
890557fa5d | ||
|
|
e27d210a71 | ||
|
|
16c08b8b47 | ||
|
|
ebd3c7f5e8 | ||
|
|
da0312a5b0 | ||
|
|
919ae8c40f | ||
|
|
dd4fccbc77 | ||
|
|
32682b5230 | ||
|
|
9dab76bb64 | ||
|
|
e6d61c6603 | ||
|
|
ee857c5128 | ||
|
|
87a4bb0888 | ||
|
|
d72cc0e201 | ||
|
|
b350b9eab9 | ||
|
|
dc112f2f3a | ||
|
|
14ae4eeac1 | ||
|
|
bbc526d0a8 | ||
|
|
abe98f5079 | ||
|
|
e8dfee8454 | ||
|
|
1746ad15d7 | ||
|
|
4d67e7fc76 | ||
|
|
3b112d2f49 | ||
|
|
93e9c1c66c | ||
|
|
8e641b3186 | ||
|
|
ed545cd9b4 | ||
|
|
bcd60c9ef7 | ||
|
|
c3d044e3f2 | ||
|
|
8d538e8f24 | ||
|
|
fa1a3d7901 | ||
|
|
3adeb925dd | ||
|
|
9de04a12e1 | ||
|
|
e01a1bb6e0 | ||
|
|
1ebea53703 | ||
|
|
ba2d6c9d93 | ||
|
|
fef0e1b77f | ||
|
|
dc1dec17b5 | ||
|
|
02ed17837b | ||
|
|
8cf996a242 | ||
|
|
02189aae07 | ||
|
|
894581ce00 | ||
|
|
fb8db01427 | ||
|
|
fa5ede93ed | ||
|
|
022a8a1017 | ||
|
|
21f6e25ab0 | ||
|
|
243e297505 | ||
|
|
9fc86f9450 | ||
|
|
e5999f5be6 | ||
|
|
3886bc16d7 | ||
|
|
7fe98bc266 | ||
|
|
2f9307fd99 | ||
|
|
3d6fa369e8 | ||
|
|
6812f508bc | ||
|
|
158cac6b0b | ||
|
|
4d10b6e1bd | ||
|
|
bb6e3b7a49 | ||
|
|
8b29dc683a | ||
|
|
d4156d78c6 | ||
|
|
c52977781e | ||
|
|
5ebc8e6f95 | ||
|
|
56d1dcafe5 | ||
|
|
393c765557 | ||
|
|
243b310eb2 | ||
|
|
cd1ecab4e0 | ||
|
|
c710953b85 | ||
|
|
70c5a30b77 | ||
|
|
9f0ba7aeae | ||
|
|
4226201423 | ||
|
|
bdf3a24be1 | ||
|
|
e8ba5581f6 | ||
|
|
948846e0f1 | ||
|
|
6c4dbb6fe6 | ||
|
|
afbabf9538 | ||
|
|
d8107122a2 | ||
|
|
03c1f08e45 | ||
|
|
760fcfcea7 | ||
|
|
a4830f5f62 | ||
|
|
2b1f337a41 | ||
|
|
ddad5f08b3 | ||
|
|
6e7933a3ce | ||
|
|
f449ff9506 | ||
|
|
a07e853f69 | ||
|
|
0d57449030 | ||
|
|
067cddd354 | ||
|
|
4af1b322da | ||
|
|
c580df15e1 | ||
|
|
b280d0ba23 | ||
|
|
439b1ade2e | ||
|
|
9f2b54eb98 | ||
|
|
278ca74a70 | ||
|
|
1c93b7bd52 | ||
|
|
2d4be347e9 | ||
|
|
26f024dc11 | ||
|
|
2b8348ea05 | ||
|
|
7cea3cefc8 | ||
|
|
693533aba2 | ||
|
|
157f9cd276 | ||
|
|
e742b5c0b8 | ||
|
|
b57d1d81ff | ||
|
|
4c97866875 | ||
|
|
8bb0cdf21b | ||
|
|
218e9b969a | ||
|
|
917d6b2214 | ||
|
|
523a855238 | ||
|
|
7a1b4b0d8b | ||
|
|
896eeff1a4 | ||
|
|
9f0d223b81 | ||
|
|
5f92ac3995 | ||
|
|
1b08aa4852 | ||
|
|
ffa2de5385 | ||
|
|
03ceb9bcab | ||
|
|
59091664db | ||
|
|
4baef92523 | ||
|
|
4528cbf407 | ||
|
|
ad8dbeab14 | ||
|
|
2746a8ebb6 | ||
|
|
27be73c707 | ||
|
|
590b60fefb |
@@ -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 =
|
||||
|
||||
35
.github/workflows/ci.yml
vendored
35
.github/workflows/ci.yml
vendored
@@ -18,32 +18,34 @@ 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 -r requirements.txt
|
||||
pip3 install poetry
|
||||
- name: Install meshtastic from local
|
||||
run: |
|
||||
pip3 install .
|
||||
which meshtastic
|
||||
meshtastic --version
|
||||
poetry install
|
||||
poetry run meshtastic --version
|
||||
- name: Run pylint
|
||||
run: pylint meshtastic examples/ --ignore-patterns ".*_pb2.py$"
|
||||
run: poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$"
|
||||
- name: Check types with mypy
|
||||
run: poetry 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@v2
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
env_vars: OS, PYTHON
|
||||
files: ./coverage.xml
|
||||
flags: unittests
|
||||
name: codecov-umbrella
|
||||
@@ -59,11 +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: |
|
||||
pip3 install .
|
||||
which meshtastic
|
||||
meshtastic --version
|
||||
python -m pip install --upgrade pip
|
||||
pip3 install poetry
|
||||
poetry install
|
||||
poetry run meshtastic --version
|
||||
|
||||
109
.github/workflows/release.yml
vendored
109
.github/workflows/release.yml
vendored
@@ -12,26 +12,36 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
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 --short | sed 's/^/::set-output name=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@v2
|
||||
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
|
||||
@@ -79,14 +72,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,21 +118,19 @@ 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: |
|
||||
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
|
||||
@@ -161,33 +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@v3
|
||||
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@v2
|
||||
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 pyinstaller
|
||||
pip install -r requirements.txt
|
||||
pip install .
|
||||
pyinstaller -F -n meshtastic --collect-all meshtastic meshtastic/__main__.py
|
||||
# - 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
|
||||
|
||||
15
.github/workflows/update_protobufs.yml
vendored
15
.github/workflows/update_protobufs.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -18,9 +18,14 @@ 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: |
|
||||
python -m pip install --upgrade pip
|
||||
pip3 install poetry
|
||||
|
||||
- name: Re-generate protocol buffers
|
||||
run: |
|
||||
@@ -32,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"
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -15,3 +15,5 @@ venv/
|
||||
__pycache__
|
||||
examples/__pycache__
|
||||
meshtastic.spec
|
||||
.hypothesis/
|
||||
coverage.xml
|
||||
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
@@ -10,7 +10,15 @@
|
||||
"request": "launch",
|
||||
"module": "meshtastic",
|
||||
"justMyCode": false,
|
||||
"args": ["--debug", "--ble", "24:62:AB:DD:DF:3A"]
|
||||
"args": ["--ble", "Meshtastic_9f6e"]
|
||||
},
|
||||
{
|
||||
"name": "meshtastic BLE scan",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "meshtastic",
|
||||
"justMyCode": false,
|
||||
"args": ["--debug", "--ble-scan"]
|
||||
},
|
||||
{
|
||||
"name": "meshtastic admin",
|
||||
@@ -76,6 +84,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",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Meshtastic Python
|
||||
|
||||
[](https://codecov.io/gh/meshtastic/Meshtastic-python)
|
||||
[](https://codecov.io/gh/meshtastic/python)
|
||||

|
||||
[](https://github.com/meshtastic/python/actions/workflows/ci.yml)
|
||||
[](https://cla-assistant.io/meshtastic/python)
|
||||
@@ -15,7 +15,7 @@ Events are delivered using a publish-subscribe model, and you can subscribe to o
|
||||
|
||||
**[Getting Started Guide](https://meshtastic.org/docs/software/python/cli/installation)**
|
||||
|
||||
**[Documentation/API Reference](https://python.meshtastic.org/)**
|
||||
(Documentation/API Reference is currently offline)
|
||||
|
||||
## Call for Contributors
|
||||
|
||||
@@ -28,8 +28,7 @@ If you're interested in contributing but don't have specific things you'd like t
|
||||
This should always be considered a list in progress and flux -- inclusion doesn't guarantee implementation, and exclusion doesn't mean something's not wanted. GitHub issues are a great place to discuss ideas.
|
||||
|
||||
* Types
|
||||
* type annotations throughout the codebase
|
||||
* mypy running in CI to type-check new code
|
||||
* type annotations throughout the codebase, and upgrading mypy running in CI to `--strict`
|
||||
* async-friendliness
|
||||
* CLI completeness & consistency
|
||||
* the CLI should support all features of the firmware
|
||||
@@ -40,9 +39,9 @@ This should always be considered a list in progress and flux -- inclusion doesn'
|
||||
* pubsub events should be documented clearly
|
||||
* helpers for third-party code
|
||||
* it should be easy to write a script that supports similar options to the CLI so many tools support the same ways of connecting to nodes
|
||||
* interactive client
|
||||
* data storage & processing
|
||||
* there should be a standardized way of recording packets for later use, debugging, etc.
|
||||
* a persistence layer could also keep track of nodes beyond nodedb, as the apps do
|
||||
* a sqlite database schema and tools for writing to it may be a good starting point
|
||||
* enable maps, charts, visualizations
|
||||
|
||||
|
||||
9
bin/build-bin.sh
Executable file
9
bin/build-bin.sh
Executable file
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
|
||||
@@ -1,20 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
#Uncomment to run hack
|
||||
#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 ./ ./protobufs/meshtastic/*.proto
|
||||
./nanopb-0.4.7/generator-bin/protoc -I=protobufs --python_out ./meshtastic/ ./protobufs/nanopb.proto
|
||||
# protoc looks for mypy plugin in the python path
|
||||
source $(poetry env info --path)/bin/activate
|
||||
|
||||
# workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628
|
||||
# Put our temp files in the poetry build directory
|
||||
TMPDIR=./build/meshtastic/protofixup
|
||||
echo "Fixing up protobuf paths in ${TMPDIR} temp directory"
|
||||
|
||||
|
||||
# Ensure a clean build
|
||||
[ -e "${TMPDIR}" ] && 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
|
||||
|
||||
11
bin/run-ci-local.sh
Executable file
11
bin/run-ci-local.sh
Executable file
@@ -0,0 +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" "$@"
|
||||
@@ -1,2 +0,0 @@
|
||||
rm log_*
|
||||
python3 -m meshtastic "$@"
|
||||
@@ -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()}")
|
||||
@@ -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"
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
"""
|
||||
# an API for Meshtastic devices
|
||||
# A library for the Meshtastic Client API
|
||||
|
||||
Primary class: SerialInterface
|
||||
Primary interfaces: SerialInterface, TCPInterface, BLEInterface
|
||||
Install with pip: "[pip3 install meshtastic](https://pypi.org/project/meshtastic/)"
|
||||
Source code on [github](https://github.com/meshtastic/python)
|
||||
|
||||
properties of SerialInterface:
|
||||
notable properties of interface classes:
|
||||
|
||||
- localConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
|
||||
the device.
|
||||
- nodes - The database of received nodes. Includes always up-to-date location and username information for each
|
||||
node in the mesh. This is a read-only datastructure.
|
||||
- nodesByNum - like "nodes" but keyed by nodeNum instead of nodeId
|
||||
- myInfo - Contains read-only information about the local radio device (software version, hardware version, etc)
|
||||
- myInfo & metadata - Contain read-only information about the local radio device (software version, hardware version, etc)
|
||||
- localNode - Pointer to a node object for the local node
|
||||
|
||||
notable properties of nodes:
|
||||
- localConfig - Current radio settings, can be written to the radio with the `writeConfig` method.
|
||||
- moduleConfig - Current module settings, can be written to the radio with the `writeConfig` method.
|
||||
- channels - The node's channels, keyed by index.
|
||||
|
||||
# Published PubSub topics
|
||||
|
||||
@@ -72,13 +76,15 @@ 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
|
||||
|
||||
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,
|
||||
@@ -90,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.
|
||||
|
||||
@@ -113,6 +119,9 @@ OUR_APP_VERSION = 20300
|
||||
format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
|
||||
"""
|
||||
|
||||
NODELESS_WANT_CONFIG_ID = 69420
|
||||
"""A special thing to pass for want_config_id that instructs nodes to skip sending nodeinfos other than its own."""
|
||||
|
||||
publishingThread = DeferredExecution("publishing")
|
||||
|
||||
|
||||
@@ -121,6 +130,7 @@ class ResponseHandler(NamedTuple):
|
||||
|
||||
# requestId: int - used only as a key
|
||||
callback: Callable
|
||||
ackPermitted: bool = False
|
||||
# FIXME, add timestamp and age out old requests
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\"meshtastic/connection_status.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\"\xa9\x10\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\x05 \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x07.ConfigH\x00\x12\x43\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\r.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x37\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x0f.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12H\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\x17.DeviceConnectionStatusH\x00\x12&\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x0e.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12Q\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x1f.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\x1a\n\tset_owner\x18 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18! \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\nset_config\x18\" \x01(\x0b\x32\x07.ConfigH\x00\x12*\n\x11set_module_config\x18# \x01(\x0b\x32\r.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\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\t.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\"[\n\x1eNodeRemoteHardwarePinsResponse\x12\x39\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32\x16.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=169
|
||||
_ADMINMESSAGE._serialized_end=2258
|
||||
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1772
|
||||
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1921
|
||||
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1924
|
||||
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=2239
|
||||
_HAMPARAMETERS._serialized_start=2260
|
||||
_HAMPARAMETERS._serialized_end=2351
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=2353
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=2444
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -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\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\"Y\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettings\x12\'\n\x0blora_config\x18\x02 \x01(\x0b\x32\x12.Config.LoRaConfigBb\n\x13\x63om.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_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=79
|
||||
_CHANNELSET._serialized_end=168
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -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\"\xaf\x01\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12\x19\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x08.Contact\x12\x15\n\x05group\x18\x03 \x01(\x0b\x32\x06.Group\x12\x17\n\x06status\x18\x04 \x01(\x0b\x32\x07.Status\x12\x13\n\x03pli\x18\x05 \x01(\x0b\x32\x04.PLIH\x00\x12\x18\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x08.GeoChatH\x00\x42\x11\n\x0fpayload_variant\"2\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x05\n\x03_to\"7\n\x05Group\x12\x19\n\x04role\x18\x01 \x01(\x0e\x32\x0b.MemberRole\x12\x13\n\x04team\x18\x02 \x01(\x0e\x32\x05.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=491
|
||||
_TEAM._serialized_end=683
|
||||
_MEMBERROLE._serialized_start=685
|
||||
_MEMBERROLE._serialized_end=812
|
||||
_TAKPACKET._serialized_start=26
|
||||
_TAKPACKET._serialized_end=201
|
||||
_GEOCHAT._serialized_start=203
|
||||
_GEOCHAT._serialized_end=253
|
||||
_GROUP._serialized_start=255
|
||||
_GROUP._serialized_end=310
|
||||
_STATUS._serialized_start=312
|
||||
_STATUS._serialized_end=337
|
||||
_CONTACT._serialized_start=339
|
||||
_CONTACT._serialized_end=391
|
||||
_PLI._serialized_start=393
|
||||
_PLI._serialized_end=488
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,139 +1,173 @@
|
||||
"""Bluetooth interface
|
||||
"""
|
||||
import logging
|
||||
import time
|
||||
import struct
|
||||
import asyncio
|
||||
from threading import Thread, Event
|
||||
from bleak import BleakScanner, BleakClient
|
||||
import atexit
|
||||
import logging
|
||||
import struct
|
||||
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
|
||||
|
||||
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"
|
||||
FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002"
|
||||
FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453"
|
||||
LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2"
|
||||
|
||||
|
||||
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"""
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
"""An exception class for BLE errors."""
|
||||
|
||||
class BLEState(): # pylint: disable=C0115
|
||||
THREADS = False
|
||||
BLE = False
|
||||
MESH = False
|
||||
|
||||
|
||||
def __init__(self, address, noProto = False, debugOut = None):
|
||||
self.state = BLEInterface.BLEState()
|
||||
|
||||
if not address:
|
||||
return
|
||||
def __init__(
|
||||
self,
|
||||
address: Optional[str],
|
||||
noProto: bool = False,
|
||||
debugOut=None,
|
||||
noNodes: bool = False,
|
||||
):
|
||||
MeshInterface.__init__(
|
||||
self, debugOut=debugOut, noProto=noProto, noNodes=noNodes
|
||||
)
|
||||
|
||||
self.should_read = False
|
||||
|
||||
logging.debug("Threads starting")
|
||||
self._receiveThread = Thread(target = self._receiveFromRadioImpl)
|
||||
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}")
|
||||
self.client = self.connect(address)
|
||||
self.state.BLE = True
|
||||
logging.debug(f"BLE connecting to: {address if address else 'any'}")
|
||||
self.client: Optional[BLEClient] = self.connect(address)
|
||||
logging.debug("BLE connected")
|
||||
except BLEInterface.BLEError as e:
|
||||
self.close()
|
||||
our_exit(e.message, 1)
|
||||
return
|
||||
raise e
|
||||
|
||||
logging.debug("Mesh init starting")
|
||||
MeshInterface.__init__(self, debugOut = debugOut, noProto = noProto)
|
||||
self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler)
|
||||
|
||||
logging.debug("Mesh configure starting")
|
||||
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")
|
||||
|
||||
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)
|
||||
# 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)
|
||||
|
||||
async def from_num_handler(self, _, b): # pylint: disable=C0116
|
||||
from_num = struct.unpack('<I', bytes(b))[0]
|
||||
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("<I", bytes(b))[0]
|
||||
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_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)
|
||||
|
||||
def scan(self):
|
||||
"Scan for available BLE devices"
|
||||
@staticmethod
|
||||
def scan() -> list[BLEDevice]:
|
||||
"""Scan for available BLE devices."""
|
||||
with BLEClient() as client:
|
||||
return [
|
||||
(x[0], x[1]) for x in (client.discover(
|
||||
return_adv = True,
|
||||
service_uuids = [ SERVICE_UUID ]
|
||||
)).values()
|
||||
]
|
||||
logging.info("Scanning for BLE devices (takes 10 seconds)...")
|
||||
response = client.discover(
|
||||
timeout=10, return_adv=True, service_uuids=[SERVICE_UUID]
|
||||
)
|
||||
|
||||
devices = response.values()
|
||||
|
||||
def find_device(self, address):
|
||||
"Find a device by address"
|
||||
meshtastic_devices = self.scan()
|
||||
# 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))
|
||||
|
||||
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))
|
||||
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 in (x.name, 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.")
|
||||
return addressed_devices[0][0]
|
||||
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):
|
||||
"Connect to a device by address"
|
||||
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)
|
||||
device = self.find_device(address)
|
||||
client = BLEClient(device.address)
|
||||
client = BLEClient(device.address, disconnected_callback=lambda _: self.close)
|
||||
client.connect()
|
||||
try:
|
||||
client.pair()
|
||||
except NotImplementedError:
|
||||
# Some bluetooth backends do not require explicit pairing.
|
||||
# See Bleak docs for details on this.
|
||||
pass
|
||||
client.discover()
|
||||
return client
|
||||
|
||||
|
||||
def _receiveFromRadioImpl(self):
|
||||
self._receiveThread_started.set()
|
||||
while self._receiveThread_started.is_set():
|
||||
while self._want_receive:
|
||||
if self.should_read:
|
||||
self.should_read = False
|
||||
retries = 0
|
||||
while True:
|
||||
b = bytes(self.client.read_gatt_char(FROMRADIO_UUID))
|
||||
while self._want_receive:
|
||||
try:
|
||||
b = bytes(self.client.read_gatt_char(FROMRADIO_UUID))
|
||||
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)
|
||||
@@ -143,40 +177,52 @@ class BLEInterface(MeshInterface):
|
||||
logging.debug(f"FROMRADIO read: {b.hex()}")
|
||||
self._handleFromRadio(b)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
self._receiveThread_stopped.set()
|
||||
time.sleep(0.01)
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
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=True
|
||||
) # FIXME: or False?
|
||||
# search Bleak src for org.bluez.Error.InProgress
|
||||
except Exception as 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):
|
||||
if self.state.MESH:
|
||||
atexit.unregister(self._exit_handler)
|
||||
try:
|
||||
MeshInterface.close(self)
|
||||
except Exception as e:
|
||||
logging.error(f"Error closing mesh interface: {e}")
|
||||
|
||||
if self.state.THREADS:
|
||||
self._receiveThread_started.clear()
|
||||
self._receiveThread_stopped.wait(5)
|
||||
if self._want_receive:
|
||||
self.want_receive = False # Tell the thread we want it to stop
|
||||
self._receiveThread.join()
|
||||
self._receiveThread = None
|
||||
|
||||
if self.state.BLE:
|
||||
if self.client:
|
||||
self.client.disconnect()
|
||||
self.client.close()
|
||||
self.client = None
|
||||
|
||||
|
||||
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)
|
||||
self._eventThread_started = Event()
|
||||
self._eventThread_stopped = Event()
|
||||
|
||||
def __init__(self, address=None, **kwargs):
|
||||
self._eventLoop = asyncio.new_event_loop()
|
||||
self._eventThread = Thread(
|
||||
target=self._run_event_loop, name="BLEClient", daemon=True
|
||||
)
|
||||
self._eventThread.start()
|
||||
self._eventThread_started.wait(1)
|
||||
|
||||
if not address:
|
||||
logging.debug("No address provided - only discover method will work.")
|
||||
@@ -184,31 +230,30 @@ 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)
|
||||
self._eventThread.join()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
@@ -216,21 +261,17 @@ class BLEClient():
|
||||
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._eventThread_started.set()
|
||||
try:
|
||||
self._eventLoop.run_forever()
|
||||
finally:
|
||||
self._eventLoop.close()
|
||||
self._eventThread_stopped.set()
|
||||
|
||||
async def _stop_event_loop(self):
|
||||
self._eventLoop.stop()
|
||||
|
||||
@@ -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\"\xad\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\x0f.ModuleSettings\",\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x62\n\x13\x63om.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_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=29
|
||||
_CHANNELSETTINGS._serialized_end=202
|
||||
_MODULESETTINGS._serialized_start=204
|
||||
_MODULESETTINGS._serialized_end=248
|
||||
_CHANNEL._serialized_start=251
|
||||
_CHANNEL._serialized_end=390
|
||||
_CHANNEL_ROLE._serialized_start=342
|
||||
_CHANNEL_ROLE._serialized_end=390
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -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\x1a\x1ameshtastic/localonly.proto\"\xf7\x01\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\x0c.LocalConfigH\x03\x88\x01\x01\x12.\n\rmodule_config\x18\x05 \x01(\x0b\x32\x12.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=60
|
||||
_DEVICEPROFILE._serialized_end=307
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
File diff suppressed because one or more lines are too long
@@ -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\"\x85\x02\n\x16\x44\x65viceConnectionStatus\x12(\n\x04wifi\x18\x01 \x01(\x0b\x32\x15.WifiConnectionStatusH\x00\x88\x01\x01\x12\x30\n\x08\x65thernet\x18\x02 \x01(\x0b\x32\x19.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x32\n\tbluetooth\x18\x03 \x01(\x0b\x32\x1a.BluetoothConnectionStatusH\x02\x88\x01\x01\x12,\n\x06serial\x18\x04 \x01(\x0b\x32\x17.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"\\\n\x14WifiConnectionStatus\x12(\n\x06status\x18\x01 \x01(\x0b\x32\x18.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"D\n\x18\x45thernetConnectionStatus\x12(\n\x06status\x18\x01 \x01(\x0b\x32\x18.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x65\n\x13\x63om.geeksville.meshB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_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=39
|
||||
_DEVICECONNECTIONSTATUS._serialized_end=300
|
||||
_WIFICONNECTIONSTATUS._serialized_start=302
|
||||
_WIFICONNECTIONSTATUS._serialized_end=394
|
||||
_ETHERNETCONNECTIONSTATUS._serialized_start=396
|
||||
_ETHERNETCONNECTIONSTATUS._serialized_end=464
|
||||
_NETWORKCONNECTIONSTATUS._serialized_start=466
|
||||
_NETWORKCONNECTIONSTATUS._serialized_end=589
|
||||
_BLUETOOTHCONNECTIONSTATUS._serialized_start=591
|
||||
_BLUETOOTHCONNECTIONSTATUS._serialized_end=667
|
||||
_SERIALCONNECTIONSTATUS._serialized_start=669
|
||||
_SERIALCONNECTIONSTATUS._serialized_end=729
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -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 telemetry_pb2 as meshtastic_dot_telemetry__pb2
|
||||
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
|
||||
from . import nanopb_pb2 as nanopb__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x1emeshtastic/module_config.proto\x1a\x0cnanopb.proto\"\xf6\x02\n\x0b\x44\x65viceState\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\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\x0b.MeshPacket\x12\x39\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32\x16.NodeRemoteHardwarePin\x12O\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32\r.NodeInfoLiteB*\x92?\'\x92\x01$std::vector<meshtastic_NodeInfoLite>\"\xe5\x01\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1f\n\x08position\x18\x03 \x01(\x0b\x32\r.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\x0e.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\"\x85\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\x13.Position.LocSource\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\xf6\x01\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x1e\n\x08oem_font\x18\x04 \x01(\x0e\x32\x0c.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12&\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x0c.LocalConfig\x12\x33\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x12.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
|
||||
|
||||
_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<vector>'
|
||||
_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<meshtastic_NodeInfoLite>'
|
||||
_SCREENFONTS._serialized_start=1236
|
||||
_SCREENFONTS._serialized_end=1298
|
||||
_DEVICESTATE._serialized_start=183
|
||||
_DEVICESTATE._serialized_end=557
|
||||
_NODEINFOLITE._serialized_start=560
|
||||
_NODEINFOLITE._serialized_end=789
|
||||
_POSITIONLITE._serialized_start=792
|
||||
_POSITIONLITE._serialized_end=925
|
||||
_CHANNELFILE._serialized_start=927
|
||||
_CHANNELFILE._serialized_end=985
|
||||
_OEMSTORE._serialized_start=988
|
||||
_OEMSTORE._serialized_end=1234
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,96 +0,0 @@
|
||||
"""Globals singleton class.
|
||||
|
||||
Instead of using a global, stuff your variables in this "trash can".
|
||||
This is not much better than using python's globals, but it allows
|
||||
us to better test meshtastic. Plus, there are some weird python
|
||||
global issues/gotcha that we can hopefully avoid by using this
|
||||
class instead.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Globals:
|
||||
"""Globals class is a Singleton."""
|
||||
|
||||
__instance = None
|
||||
|
||||
@staticmethod
|
||||
def getInstance():
|
||||
"""Get an instance of the Globals class."""
|
||||
if Globals.__instance is None:
|
||||
Globals()
|
||||
return Globals.__instance
|
||||
|
||||
def __init__(self):
|
||||
"""Constructor for the Globals CLass"""
|
||||
if Globals.__instance is not None:
|
||||
raise Exception("This class is a singleton") # pylint: disable=W0719
|
||||
else:
|
||||
Globals.__instance = self
|
||||
self.args = None
|
||||
self.parser = None
|
||||
self.channel_index = None
|
||||
self.logfile = None
|
||||
self.tunnelInstance = None
|
||||
# TODO: to migrate to camel_case for v1.3 change this value to True
|
||||
self.camel_case = False
|
||||
|
||||
def reset(self):
|
||||
"""Reset all of our globals. If you add a member, add it to this method, too."""
|
||||
self.args = None
|
||||
self.parser = None
|
||||
self.channel_index = None
|
||||
self.logfile = None
|
||||
self.tunnelInstance = None
|
||||
# TODO: to migrate to camel_case for v1.3 change this value to True
|
||||
self.camel_case = False
|
||||
|
||||
# setters
|
||||
def set_args(self, args):
|
||||
"""Set the args"""
|
||||
self.args = args
|
||||
|
||||
def set_parser(self, parser):
|
||||
"""Set the parser"""
|
||||
self.parser = parser
|
||||
|
||||
def set_channel_index(self, channel_index):
|
||||
"""Set the channel_index"""
|
||||
self.channel_index = channel_index
|
||||
|
||||
def set_logfile(self, logfile):
|
||||
"""Set the logfile"""
|
||||
self.logfile = logfile
|
||||
|
||||
def set_tunnelInstance(self, tunnelInstance):
|
||||
"""Set the tunnelInstance"""
|
||||
self.tunnelInstance = tunnelInstance
|
||||
|
||||
def set_camel_case(self):
|
||||
"""Force using camelCase for things like prefs/set/set"""
|
||||
self.camel_case = True
|
||||
|
||||
# getters
|
||||
def get_args(self):
|
||||
"""Get args"""
|
||||
return self.args
|
||||
|
||||
def get_parser(self):
|
||||
"""Get parser"""
|
||||
return self.parser
|
||||
|
||||
def get_channel_index(self):
|
||||
"""Get channel_index"""
|
||||
return self.channel_index
|
||||
|
||||
def get_logfile(self):
|
||||
"""Get logfile"""
|
||||
return self.logfile
|
||||
|
||||
def get_tunnelInstance(self):
|
||||
"""Get tunnelInstance"""
|
||||
return self.tunnelInstance
|
||||
|
||||
def get_camel_case(self):
|
||||
"""Get whether or not to use camelCase"""
|
||||
return self.camel_case
|
||||
@@ -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\x1a\x17meshtastic/config.proto\x1a\x1emeshtastic/module_config.proto\"\xb0\x02\n\x0bLocalConfig\x12$\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x14.Config.DeviceConfig\x12(\n\x08position\x18\x02 \x01(\x0b\x32\x16.Config.PositionConfig\x12\"\n\x05power\x18\x03 \x01(\x0b\x32\x13.Config.PowerConfig\x12&\n\x07network\x18\x04 \x01(\x0b\x32\x15.Config.NetworkConfig\x12&\n\x07\x64isplay\x18\x05 \x01(\x0b\x32\x15.Config.DisplayConfig\x12 \n\x04lora\x18\x06 \x01(\x0b\x32\x12.Config.LoRaConfig\x12*\n\tbluetooth\x18\x07 \x01(\x0b\x32\x17.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\"\xec\x05\n\x11LocalModuleConfig\x12&\n\x04mqtt\x18\x01 \x01(\x0b\x32\x18.ModuleConfig.MQTTConfig\x12*\n\x06serial\x18\x02 \x01(\x0b\x32\x1a.ModuleConfig.SerialConfig\x12G\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32(.ModuleConfig.ExternalNotificationConfig\x12\x37\n\rstore_forward\x18\x04 \x01(\x0b\x32 .ModuleConfig.StoreForwardConfig\x12\x31\n\nrange_test\x18\x05 \x01(\x0b\x32\x1d.ModuleConfig.RangeTestConfig\x12\x30\n\ttelemetry\x18\x06 \x01(\x0b\x32\x1d.ModuleConfig.TelemetryConfig\x12\x39\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32!.ModuleConfig.CannedMessageConfig\x12(\n\x05\x61udio\x18\t \x01(\x0b\x32\x19.ModuleConfig.AudioConfig\x12;\n\x0fremote_hardware\x18\n \x01(\x0b\x32\".ModuleConfig.RemoteHardwareConfig\x12\x37\n\rneighbor_info\x18\x0b \x01(\x0b\x32 .ModuleConfig.NeighborInfoConfig\x12=\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32#.ModuleConfig.AmbientLightingConfig\x12=\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32#.ModuleConfig.DetectionSensorConfig\x12\x32\n\npaxcounter\x18\x0e \x01(\x0b\x32\x1e.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=88
|
||||
_LOCALCONFIG._serialized_end=392
|
||||
_LOCALMODULECONFIG._serialized_start=395
|
||||
_LOCALMODULECONFIG._serialized_end=1143
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -9,20 +9,26 @@ import sys
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import AnyStr
|
||||
from decimal import Decimal
|
||||
|
||||
from typing import Any, Callable, Dict, List, Optional, Union
|
||||
|
||||
import google.protobuf.json_format
|
||||
import timeago
|
||||
from google.protobuf.json_format import MessageToJson
|
||||
from pubsub import pub
|
||||
from pubsub import pub # type: ignore[import-untyped]
|
||||
from tabulate import tabulate
|
||||
|
||||
import meshtastic.node
|
||||
from meshtastic import mesh_pb2, portnums_pb2, telemetry_pb2
|
||||
from meshtastic.__init__ import (
|
||||
|
||||
from meshtastic.protobuf import (
|
||||
mesh_pb2,
|
||||
portnums_pb2,
|
||||
telemetry_pb2,
|
||||
)
|
||||
from meshtastic import (
|
||||
BROADCAST_ADDR,
|
||||
BROADCAST_NUM,
|
||||
LOCAL_ADDR,
|
||||
NODELESS_WANT_CONFIG_ID,
|
||||
ResponseHandler,
|
||||
protocols,
|
||||
publishingThread,
|
||||
@@ -34,10 +40,34 @@ from meshtastic.util import (
|
||||
our_exit,
|
||||
remove_keys_from_dict,
|
||||
stripnl,
|
||||
message_to_json,
|
||||
)
|
||||
|
||||
|
||||
class MeshInterface:
|
||||
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
|
||||
|
||||
Properties:
|
||||
@@ -53,35 +83,39 @@ class MeshInterface:
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
def __init__(self, debugOut=None, noProto=False):
|
||||
def __init__(self, debugOut=None, noProto: bool=False, noNodes: bool=False) -> None:
|
||||
"""Constructor
|
||||
|
||||
Keyword Arguments:
|
||||
noProto -- If True, don't try to run our protocol on the
|
||||
link - just be a dumb serial client.
|
||||
noNodes -- If True, instruct the node to not send its nodedb
|
||||
on startup, just other configuration information.
|
||||
"""
|
||||
self.debugOut = debugOut
|
||||
self.nodes = None # FIXME
|
||||
self.isConnected = threading.Event()
|
||||
self.noProto = noProto
|
||||
self.localNode = meshtastic.node.Node(self, -1) # We fixup nodenum later
|
||||
self.myInfo = None # We don't have device info yet
|
||||
self.metadata = None # We don't have device metadata yet
|
||||
self.responseHandlers = {} # A map from request ID to the handler
|
||||
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.failure = (
|
||||
None # If we've encountered a fatal exception it will be kept here
|
||||
)
|
||||
self._timeout = Timeout()
|
||||
self._acknowledgment = Acknowledgment()
|
||||
self.heartbeatTimer = None
|
||||
self._timeout: Timeout = Timeout()
|
||||
self._acknowledgment: Acknowledgment = Acknowledgment()
|
||||
self.heartbeatTimer: Optional[threading.Timer] = None
|
||||
random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it
|
||||
self.currentPacketId = random.randint(0, 0xFFFFFFFF)
|
||||
self.nodesByNum = None
|
||||
self.configId = None
|
||||
self.gotResponse = False # used in gpio read
|
||||
self.mask = None # used in gpio read and gpio watch
|
||||
self.queueStatus = None
|
||||
self.queue = collections.OrderedDict()
|
||||
self.currentPacketId: int = random.randint(0, 0xFFFFFFFF)
|
||||
self.nodesByNum: Optional[Dict[int, Dict]] = None
|
||||
self.noNodes: bool = noNodes
|
||||
self.configId: Optional[int] = NODELESS_WANT_CONFIG_ID if noNodes else None
|
||||
self.gotResponse: bool = False # used in gpio read
|
||||
self.mask: Optional[int] = None # used in gpio read and gpio watch
|
||||
self.queueStatus: Optional[mesh_pb2.QueueStatus] = None
|
||||
self.queue: collections.OrderedDict = collections.OrderedDict()
|
||||
self._localChannels = None
|
||||
|
||||
def close(self):
|
||||
"""Shutdown this interface"""
|
||||
@@ -102,15 +136,15 @@ class MeshInterface:
|
||||
logging.error(f"Traceback: {traceback}")
|
||||
self.close()
|
||||
|
||||
def showInfo(self, file=sys.stdout): # pylint: disable=W0613
|
||||
def showInfo(self, file=sys.stdout) -> str: # pylint: disable=W0613
|
||||
"""Show human readable summary about this object"""
|
||||
owner = f"Owner: {self.getLongName()} ({self.getShortName()})"
|
||||
myinfo = ""
|
||||
if self.myInfo:
|
||||
myinfo = f"\nMy info: {stripnl(MessageToJson(self.myInfo))}"
|
||||
myinfo = f"\nMy info: {message_to_json(self.myInfo)}"
|
||||
metadata = ""
|
||||
if self.metadata:
|
||||
metadata = f"\nMetadata: {stripnl(MessageToJson(self.metadata))}"
|
||||
metadata = f"\nMetadata: {message_to_json(self.metadata)}"
|
||||
mesh = "\n\nNodes in mesh: "
|
||||
nodes = {}
|
||||
if self.nodes:
|
||||
@@ -130,39 +164,42 @@ class MeshInterface:
|
||||
# use id as dictionary key for correct json format in list of nodes
|
||||
nodeid = n2["user"]["id"]
|
||||
nodes[nodeid] = n2
|
||||
infos = owner + myinfo + metadata + mesh + json.dumps(nodes)
|
||||
infos = owner + myinfo + metadata + mesh + json.dumps(nodes, indent=2)
|
||||
print(infos)
|
||||
return infos
|
||||
|
||||
def showNodes(self, includeSelf=True, file=sys.stdout): # 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=""):
|
||||
def formatFloat(value, precision=2, unit="") -> Optional[str]:
|
||||
"""Format a float value with precision."""
|
||||
return f"{value:.{precision}f}{unit}" if value else None
|
||||
|
||||
def getLH(ts):
|
||||
def getLH(ts) -> Optional[str]:
|
||||
"""Format last heard"""
|
||||
return (
|
||||
datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S") if ts else None
|
||||
)
|
||||
|
||||
def getTimeAgo(ts):
|
||||
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
|
||||
return _timeago(delta_secs)
|
||||
|
||||
rows = []
|
||||
rows: List[Dict[str, Any]] = []
|
||||
if self.nodesByNum:
|
||||
logging.debug(f"self.nodes:{self.nodes}")
|
||||
for node in self.nodesByNum.values():
|
||||
if not includeSelf and node["num"] == self.localNode.nodeNum:
|
||||
continue
|
||||
|
||||
row = {"N": 0, "User": f"UNK: {node['num']}", "ID": f"!{node['num']:x}"}
|
||||
presumptive_id = f"!{node['num']:08x}"
|
||||
row = {"N": 0, "User": f"Meshtastic {presumptive_id[-4:]}", "ID": presumptive_id}
|
||||
|
||||
user = node.get("user")
|
||||
if user:
|
||||
@@ -171,6 +208,7 @@ class MeshInterface:
|
||||
"User": user.get("longName", "N/A"),
|
||||
"AKA": user.get("shortName", "N/A"),
|
||||
"ID": user["id"],
|
||||
"Hardware": user.get("hwModel", "UNSET")
|
||||
}
|
||||
)
|
||||
|
||||
@@ -207,7 +245,8 @@ class MeshInterface:
|
||||
row.update(
|
||||
{
|
||||
"SNR": formatFloat(node.get("snr"), 2, " dB"),
|
||||
"Channel": node.get("channel"),
|
||||
"Hops Away": node.get("hopsAway", "0/unknown"),
|
||||
"Channel": node.get("channel", 0),
|
||||
"LastHeard": getLH(node.get("lastHeard")),
|
||||
"Since": getTimeAgo(node.get("lastHeard")),
|
||||
}
|
||||
@@ -223,7 +262,7 @@ class MeshInterface:
|
||||
print(table)
|
||||
return table
|
||||
|
||||
def getNode(self, nodeId, requestChannels=True):
|
||||
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
|
||||
@@ -239,12 +278,12 @@ class MeshInterface:
|
||||
|
||||
def sendText(
|
||||
self,
|
||||
text: AnyStr,
|
||||
destinationId=BROADCAST_ADDR,
|
||||
wantAck=False,
|
||||
wantResponse=False,
|
||||
onResponse=None,
|
||||
channelIndex=0,
|
||||
text: str,
|
||||
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.
|
||||
@@ -279,12 +318,13 @@ class MeshInterface:
|
||||
def sendData(
|
||||
self,
|
||||
data,
|
||||
destinationId=BROADCAST_ADDR,
|
||||
portNum=portnums_pb2.PortNum.PRIVATE_APP,
|
||||
wantAck=False,
|
||||
wantResponse=False,
|
||||
onResponse=None,
|
||||
channelIndex=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
|
||||
|
||||
@@ -303,6 +343,10 @@ class MeshInterface:
|
||||
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
|
||||
@@ -333,19 +377,21 @@ class MeshInterface:
|
||||
meshPacket.id = self._generatePacketId()
|
||||
|
||||
if onResponse is not None:
|
||||
self._addResponseHandler(meshPacket.id, onResponse)
|
||||
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)
|
||||
return p
|
||||
|
||||
def sendPosition(
|
||||
self,
|
||||
latitude=0.0,
|
||||
longitude=0.0,
|
||||
altitude=0,
|
||||
timeSec=0,
|
||||
destinationId=BROADCAST_ADDR,
|
||||
wantAck=False,
|
||||
wantResponse=False,
|
||||
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)
|
||||
@@ -372,19 +418,57 @@ class MeshInterface:
|
||||
logging.debug(f"p.altitude:{p.altitude}")
|
||||
|
||||
if timeSec == 0:
|
||||
timeSec = time.time() # returns unix timestamp in seconds
|
||||
p.time = int(timeSec)
|
||||
timeSec = int(time.time()) # returns unix timestamp in seconds
|
||||
p.time = timeSec
|
||||
logging.debug(f"p.time:{p.time}")
|
||||
|
||||
return self.sendData(
|
||||
if wantResponse:
|
||||
onResponse = self.onResponsePosition
|
||||
else:
|
||||
onResponse = None
|
||||
|
||||
d = self.sendData(
|
||||
p,
|
||||
destinationId,
|
||||
portNum=portnums_pb2.PortNum.POSITION_APP,
|
||||
wantAck=wantAck,
|
||||
wantResponse=wantResponse,
|
||||
onResponse=onResponse,
|
||||
channelIndex=channelIndex,
|
||||
)
|
||||
if wantResponse:
|
||||
self.waitForPosition()
|
||||
return d
|
||||
|
||||
def sendTraceRoute(self, dest, hopLimit):
|
||||
def onResponsePosition(self, p):
|
||||
"""on response for position"""
|
||||
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})"
|
||||
else:
|
||||
ret += "(unknown)"
|
||||
if position.altitude != 0:
|
||||
ret += f" {position.altitude}m"
|
||||
|
||||
if position.precision_bits not in [0,32]:
|
||||
ret += f" precision:{position.precision_bits}"
|
||||
elif position.precision_bits == 32:
|
||||
ret += " full precision"
|
||||
elif position.precision_bits == 0:
|
||||
ret += " position disabled"
|
||||
|
||||
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.")
|
||||
|
||||
def sendTraceRoute(self, dest: Union[int, str], hopLimit: int, channelIndex: int=0):
|
||||
"""Send the trace route"""
|
||||
r = mesh_pb2.RouteDiscovery()
|
||||
self.sendData(
|
||||
@@ -393,12 +477,13 @@ class MeshInterface:
|
||||
portNum=portnums_pb2.PortNum.TRACEROUTE_APP,
|
||||
wantResponse=True,
|
||||
onResponse=self.onResponseTraceRoute,
|
||||
channelIndex=channelIndex,
|
||||
)
|
||||
# extend timeout based on number of nodes, limit by configured hopLimit
|
||||
waitFactor = min(len(self.nodes) - 1, hopLimit)
|
||||
waitFactor = min(len(self.nodes) - 1 if self.nodes else 0, hopLimit)
|
||||
self.waitForTraceRoute(waitFactor)
|
||||
|
||||
def onResponseTraceRoute(self, p):
|
||||
def onResponseTraceRoute(self, p: dict):
|
||||
"""on response for trace route"""
|
||||
routeDiscovery = mesh_pb2.RouteDiscovery()
|
||||
routeDiscovery.ParseFromString(p["decoded"]["payload"])
|
||||
@@ -414,48 +499,45 @@ class MeshInterface:
|
||||
|
||||
self._acknowledgment.receivedTraceRoute = True
|
||||
|
||||
def sendTelemetry(self, destinationId=BROADCAST_ADDR, wantResponse=False):
|
||||
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()
|
||||
|
||||
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:
|
||||
batteryLevel = metrics.get("batteryLevel")
|
||||
if batteryLevel is not None:
|
||||
r.device_metrics.battery_level = batteryLevel
|
||||
voltage = metrics.get("voltage")
|
||||
if voltage is not None:
|
||||
r.device_metrics.voltage = voltage
|
||||
channel_utilization = metrics.get("channelUtilization")
|
||||
if channel_utilization is not None:
|
||||
r.device_metrics.channel_utilization = channel_utilization
|
||||
air_util_tx = metrics.get("airUtilTx")
|
||||
if air_util_tx is not None:
|
||||
r.device_metrics.air_util_tx = air_util_tx
|
||||
if self.nodes is not None:
|
||||
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:
|
||||
batteryLevel = metrics.get("batteryLevel")
|
||||
if batteryLevel is not None:
|
||||
r.device_metrics.battery_level = batteryLevel
|
||||
voltage = metrics.get("voltage")
|
||||
if voltage is not None:
|
||||
r.device_metrics.voltage = voltage
|
||||
channel_utilization = metrics.get("channelUtilization")
|
||||
if channel_utilization is not None:
|
||||
r.device_metrics.channel_utilization = channel_utilization
|
||||
air_util_tx = metrics.get("airUtilTx")
|
||||
if air_util_tx is not None:
|
||||
r.device_metrics.air_util_tx = air_util_tx
|
||||
|
||||
if wantResponse:
|
||||
onResponse = self.onResponseTelemetry
|
||||
else:
|
||||
onResponse = None
|
||||
|
||||
if destinationId.startswith("!"):
|
||||
destinationId = int(destinationId[1:], 16)
|
||||
else:
|
||||
destinationId = int(destinationId)
|
||||
|
||||
self.sendData(
|
||||
r,
|
||||
destinationId=destinationId,
|
||||
portNum=portnums_pb2.PortNum.TELEMETRY_APP,
|
||||
wantResponse=wantResponse,
|
||||
onResponse=onResponse,
|
||||
channelIndex=channelIndex,
|
||||
)
|
||||
if wantResponse:
|
||||
self.waitForTelemetry()
|
||||
|
||||
def onResponseTelemetry(self, p):
|
||||
def onResponseTelemetry(self, p: dict):
|
||||
"""on response for telemetry"""
|
||||
if p["decoded"]["portnum"] == 'TELEMETRY_APP':
|
||||
self._acknowledgment.receivedTelemetry = True
|
||||
@@ -478,10 +560,10 @@ class MeshInterface:
|
||||
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, callback):
|
||||
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, destinationId=BROADCAST_ADDR, wantAck=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.
|
||||
|
||||
@@ -495,7 +577,7 @@ class MeshInterface:
|
||||
|
||||
toRadio = mesh_pb2.ToRadio()
|
||||
|
||||
nodeNum = 0
|
||||
nodeNum: int = 0
|
||||
if destinationId is None:
|
||||
our_exit("Warning: destinationId must not be None")
|
||||
elif isinstance(destinationId, int):
|
||||
@@ -513,9 +595,10 @@ class MeshInterface:
|
||||
else:
|
||||
if self.nodes:
|
||||
node = self.nodes.get(destinationId)
|
||||
if not node:
|
||||
if node is None:
|
||||
our_exit(f"Warning: NodeId {destinationId} not found in DB")
|
||||
nodeNum = node["num"]
|
||||
else:
|
||||
nodeNum = node["num"]
|
||||
else:
|
||||
logging.warning("Warning: There were no self.nodes.")
|
||||
|
||||
@@ -567,9 +650,15 @@ class MeshInterface:
|
||||
if not success:
|
||||
raise MeshInterface.MeshInterfaceError("Timed out waiting for telemetry")
|
||||
|
||||
def getMyNodeInfo(self):
|
||||
def waitForPosition(self):
|
||||
"""Wait for position"""
|
||||
success = self._timeout.waitForPosition(self._acknowledgment)
|
||||
if not success:
|
||||
raise MeshInterface.MeshInterfaceError("Timed out waiting for position")
|
||||
|
||||
def getMyNodeInfo(self) -> Optional[Dict]:
|
||||
"""Get info about my node."""
|
||||
if self.myInfo is None:
|
||||
if self.myInfo is None or self.nodesByNum is None:
|
||||
return None
|
||||
logging.debug(f"self.nodesByNum:{self.nodesByNum}")
|
||||
return self.nodesByNum.get(self.myInfo.my_node_num)
|
||||
@@ -606,7 +695,7 @@ class MeshInterface:
|
||||
if self.failure:
|
||||
raise self.failure
|
||||
|
||||
def _generatePacketId(self):
|
||||
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")
|
||||
@@ -633,6 +722,7 @@ class MeshInterface:
|
||||
self.heartbeatTimer = threading.Timer(i, callback)
|
||||
self.heartbeatTimer.start()
|
||||
p = mesh_pb2.ToRadio()
|
||||
p.heartbeat.CopyFrom(mesh_pb2.Heartbeat())
|
||||
self._sendToRadio(p)
|
||||
|
||||
callback() # run our periodic callback now, it will make another timer if necessary
|
||||
@@ -656,9 +746,11 @@ class MeshInterface:
|
||||
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)
|
||||
|
||||
startConfig = mesh_pb2.ToRadio()
|
||||
self.configId = random.randint(0, 0xFFFFFFFF)
|
||||
if self.configId is None or not self.noNodes:
|
||||
self.configId = random.randint(0, 0xFFFFFFFF)
|
||||
startConfig.want_config_id = self.configId
|
||||
self._sendToRadio(startConfig)
|
||||
|
||||
@@ -668,18 +760,18 @@ class MeshInterface:
|
||||
m.disconnect = True
|
||||
self._sendToRadio(m)
|
||||
|
||||
def _queueHasFreeSpace(self):
|
||||
def _queueHasFreeSpace(self) -> bool:
|
||||
# We never got queueStatus, maybe the firmware is old
|
||||
if self.queueStatus is None:
|
||||
return True
|
||||
return self.queueStatus.free > 0
|
||||
|
||||
def _queueClaim(self):
|
||||
def _queueClaim(self) -> None:
|
||||
if self.queueStatus is None:
|
||||
return
|
||||
self.queueStatus.free -= 1
|
||||
|
||||
def _sendToRadio(self, toRadio):
|
||||
def _sendToRadio(self, toRadio: mesh_pb2.ToRadio) -> None:
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
if self.noProto:
|
||||
logging.warning(
|
||||
@@ -728,18 +820,23 @@ class MeshInterface:
|
||||
self.queue[packetId] = packet
|
||||
# logging.warn("queue + resentQueue: " + " ".join(f'{k:08x}' for k in self.queue))
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
def _sendToRadioImpl(self, toRadio: mesh_pb2.ToRadio) -> None:
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
logging.error(f"Subclass must provide toradio: {toRadio}")
|
||||
|
||||
def _handleConfigComplete(self):
|
||||
def _handleConfigComplete(self) -> None:
|
||||
"""
|
||||
Done with initial config messages, now send regular MeshPackets
|
||||
to ask for settings and channels
|
||||
"""
|
||||
self.localNode.requestChannels()
|
||||
# This is no longer necessary because the current protocol statemachine has already proactively sent us the locally visible channels
|
||||
# self.localNode.requestChannels()
|
||||
self.localNode.setChannels(self._localChannels)
|
||||
|
||||
def _handleQueueStatusFromRadio(self, queueStatus):
|
||||
# the following should only be called after we have settings and channels
|
||||
self._connected() # Tell everyone else we are ready to go
|
||||
|
||||
def _handleQueueStatusFromRadio(self, queueStatus) -> None:
|
||||
self.queueStatus = queueStatus
|
||||
logging.debug(
|
||||
f"TX QUEUE free {queueStatus.free} of {queueStatus.maxlen}, res = {queueStatus.res}, id = {queueStatus.mesh_packet_id:08x} "
|
||||
@@ -787,16 +884,18 @@ class MeshInterface:
|
||||
logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
|
||||
|
||||
elif fromRadio.HasField("node_info"):
|
||||
node = asDict["nodeInfo"]
|
||||
logging.debug(f"Received nodeinfo: {asDict['nodeInfo']}")
|
||||
|
||||
node = self._getOrCreateByNum(asDict["nodeInfo"]["num"])
|
||||
node.update(asDict["nodeInfo"])
|
||||
try:
|
||||
newpos = self._fixupPosition(node["position"])
|
||||
node["position"] = newpos
|
||||
except:
|
||||
logging.debug("Node without position")
|
||||
|
||||
logging.debug(f"Received nodeinfo: {node}")
|
||||
|
||||
self.nodesByNum[node["num"]] = node
|
||||
# no longer necessary since we're mutating directly in nodesByNum via _getOrCreateByNum
|
||||
#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
|
||||
@@ -810,21 +909,36 @@ class MeshInterface:
|
||||
# stream API fromRadio.config_complete_id
|
||||
logging.debug(f"Config complete ID {self.configId}")
|
||||
self._handleConfigComplete()
|
||||
|
||||
elif fromRadio.HasField("channel"):
|
||||
self._handleChannel(fromRadio.channel)
|
||||
elif fromRadio.HasField("packet"):
|
||||
self._handlePacketFromRadio(fromRadio.packet)
|
||||
|
||||
elif fromRadio.HasField("queueStatus"):
|
||||
self._handleQueueStatusFromRadio(fromRadio.queueStatus)
|
||||
|
||||
elif fromRadio.rebooted:
|
||||
elif fromRadio.HasField("mqttClientProxyMessage"):
|
||||
publishingThread.queueWork(
|
||||
lambda: pub.sendMessage(
|
||||
"meshtastic.mqttclientproxymessage", proxymessage=fromRadio.mqttClientProxyMessage, interface=self
|
||||
)
|
||||
)
|
||||
|
||||
elif fromRadio.HasField("xmodemPacket"):
|
||||
publishingThread.queueWork(
|
||||
lambda: pub.sendMessage(
|
||||
"meshtastic.xmodempacket", packet=fromRadio.xmodemPacket, interface=self
|
||||
)
|
||||
)
|
||||
|
||||
elif fromRadio.HasField("rebooted") and fromRadio.rebooted:
|
||||
# Tell clients the device went away. Careful not to call the overridden
|
||||
# subclass version that closes the serial port
|
||||
MeshInterface._disconnected(self)
|
||||
|
||||
self._startConfig() # redownload the node db etc...
|
||||
|
||||
elif fromRadio.config or fromRadio.moduleConfig:
|
||||
elif fromRadio.HasField("config") or fromRadio.HasField("moduleConfig"):
|
||||
if fromRadio.config.HasField("device"):
|
||||
self.localNode.localConfig.device.CopyFrom(fromRadio.config.device)
|
||||
elif fromRadio.config.HasField("position"):
|
||||
@@ -852,6 +966,10 @@ class MeshInterface:
|
||||
self.localNode.moduleConfig.external_notification.CopyFrom(
|
||||
fromRadio.moduleConfig.external_notification
|
||||
)
|
||||
elif fromRadio.moduleConfig.HasField("store_forward"):
|
||||
self.localNode.moduleConfig.store_forward.CopyFrom(
|
||||
fromRadio.moduleConfig.store_forward
|
||||
)
|
||||
elif fromRadio.moduleConfig.HasField("range_test"):
|
||||
self.localNode.moduleConfig.range_test.CopyFrom(
|
||||
fromRadio.moduleConfig.range_test
|
||||
@@ -890,7 +1008,7 @@ class MeshInterface:
|
||||
else:
|
||||
logging.debug("Unexpected FromRadio payload")
|
||||
|
||||
def _fixupPosition(self, position):
|
||||
def _fixupPosition(self, position: Dict) -> Dict:
|
||||
"""Convert integer lat/lon into floats
|
||||
|
||||
Arguments:
|
||||
@@ -898,9 +1016,9 @@ class MeshInterface:
|
||||
Returns the position with the updated keys
|
||||
"""
|
||||
if "latitudeI" in position:
|
||||
position["latitude"] = position["latitudeI"] * 1e-7
|
||||
position["latitude"] = float(position["latitudeI"] * Decimal("1e-7"))
|
||||
if "longitudeI" in position:
|
||||
position["longitude"] = position["longitudeI"] * 1e-7
|
||||
position["longitude"] = float(position["longitudeI"] * Decimal("1e-7"))
|
||||
return position
|
||||
|
||||
def _nodeNumToId(self, num):
|
||||
@@ -929,10 +1047,23 @@ class MeshInterface:
|
||||
if nodeNum in self.nodesByNum:
|
||||
return self.nodesByNum[nodeNum]
|
||||
else:
|
||||
n = {"num": nodeNum} # Create a minimal node db entry
|
||||
presumptive_id = f"!{nodeNum:08x}"
|
||||
n = {
|
||||
"num": nodeNum,
|
||||
"user": {
|
||||
"id": presumptive_id,
|
||||
"longName": f"Meshtastic {presumptive_id[-4:]}",
|
||||
"shortName": f"{presumptive_id[-4:]}",
|
||||
"hwModel": "UNSET"
|
||||
}
|
||||
} # Create a minimal node db entry
|
||||
self.nodesByNum[nodeNum] = n
|
||||
return n
|
||||
|
||||
def _handleChannel(self, channel):
|
||||
"""During initial config the local node will proactively send all N (8) channels it knows"""
|
||||
self._localChannels.append(channel)
|
||||
|
||||
def _handlePacketFromRadio(self, meshPacket, hack=False):
|
||||
"""Handle a MeshPacket that just arrived from the radio
|
||||
|
||||
@@ -1029,15 +1160,19 @@ class MeshInterface:
|
||||
# Is this message in response to a request, if so, look for a handler
|
||||
requestId = decoded.get("requestId")
|
||||
if requestId is not None:
|
||||
# We ignore ACK packets, but send NAKs and data responses to the handlers
|
||||
logging.debug(f"Got a response for requestId {requestId}")
|
||||
# We ignore ACK packets unless the callback is named `onAckNak`
|
||||
# or the handler is set as ackPermitted, but send NAKs and
|
||||
# other, data-containing responses to the handlers
|
||||
routing = decoded.get("routing")
|
||||
isAck = routing is not None and ("errorReason" not in routing)
|
||||
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"):
|
||||
handler.callback(asDict)
|
||||
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:
|
||||
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(
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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 mesh_pb2 as meshtastic_dot_mesh__pb2
|
||||
from meshtastic import config_pb2 as meshtastic_dot_config__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15meshtastic/mqtt.proto\x1a\x15meshtastic/mesh.proto\x1a\x17meshtastic/config.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\x90\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\x19.Config.DeviceConfig.Role\x12 \n\x08hw_model\x18\x04 \x01(\x0e\x32\x0e.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12-\n\x06region\x18\x06 \x01(\x0e\x32\x1d.Config.LoRaConfig.RegionCode\x12\x34\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x1e.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=73
|
||||
_SERVICEENVELOPE._serialized_end=159
|
||||
_MAPREPORT._serialized_start=162
|
||||
_MAPREPORT._serialized_end=562
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
37
meshtastic/mt_config.py
Normal file
37
meshtastic/mt_config.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
Globals singleton class.
|
||||
|
||||
The Global object is gone, as are all its setters and getters. Instead the
|
||||
module itself is the singleton namespace, which can be imported into
|
||||
whichever module is used. The associated tests have also been removed,
|
||||
since we now rely on built in Python mechanisms.
|
||||
|
||||
This is intended to make the Python read more naturally, and to make the
|
||||
intention of the code clearer and more compact. It is merely a sticking
|
||||
plaster over the use of shared mt_config, but the coupling issues wil be dealt
|
||||
with rather more easily once the code is simplified by this change.
|
||||
|
||||
"""
|
||||
|
||||
def reset():
|
||||
"""
|
||||
Restore the namespace to pristine condition.
|
||||
"""
|
||||
# pylint: disable=W0603
|
||||
global args, parser, channel_index, logfile, tunnelInstance, camel_case
|
||||
args = None
|
||||
parser = None
|
||||
channel_index = None
|
||||
logfile = None
|
||||
tunnelInstance = None
|
||||
# TODO: to migrate to camel_case for v1.3 change this value to True
|
||||
camel_case = False
|
||||
|
||||
# These assignments are used instead of calling reset()
|
||||
# purely to shut pylint up.
|
||||
args = None
|
||||
parser = None
|
||||
channel_index = None
|
||||
logfile = None
|
||||
tunnelInstance = None
|
||||
camel_case = False
|
||||
@@ -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)
|
||||
@@ -5,9 +5,9 @@ import base64
|
||||
import logging
|
||||
import time
|
||||
|
||||
from google.protobuf.json_format import MessageToJson
|
||||
from typing import Union
|
||||
|
||||
from meshtastic import admin_pb2, apponly_pb2, channel_pb2, localonly_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,
|
||||
@@ -15,6 +15,7 @@ from meshtastic.util import (
|
||||
our_exit,
|
||||
pskToString,
|
||||
stripnl,
|
||||
message_to_json,
|
||||
)
|
||||
|
||||
|
||||
@@ -47,8 +48,7 @@ class Node:
|
||||
if self.channels:
|
||||
logging.debug(f"self.channels:{self.channels}")
|
||||
for c in self.channels:
|
||||
# print('c.settings.psk:', c.settings.psk)
|
||||
cStr = stripnl(MessageToJson(c.settings))
|
||||
cStr = message_to_json(c.settings)
|
||||
# don't show disabled channels
|
||||
if channel_pb2.Channel.Role.Name(c.role) != "DISABLED":
|
||||
print(
|
||||
@@ -64,14 +64,19 @@ class Node:
|
||||
"""Show human readable description of our node"""
|
||||
prefs = ""
|
||||
if self.localConfig:
|
||||
prefs = stripnl(MessageToJson(self.localConfig))
|
||||
prefs = message_to_json(self.localConfig, multiline=True)
|
||||
print(f"Preferences: {prefs}\n")
|
||||
prefs = ""
|
||||
if self.moduleConfig:
|
||||
prefs = stripnl(MessageToJson(self.moduleConfig))
|
||||
prefs = message_to_json(self.moduleConfig, multiline=True)
|
||||
print(f"Module preferences: {prefs}\n")
|
||||
self.showChannels()
|
||||
|
||||
def setChannels(self, channels):
|
||||
"""Set the channels for this node"""
|
||||
self.channels = channels
|
||||
self._fixupChannels()
|
||||
|
||||
def requestChannels(self):
|
||||
"""Send regular MeshPackets to ask channels."""
|
||||
logging.debug(f"requestChannels for nodeNum:{self.nodeNum}")
|
||||
@@ -123,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 == "LocalConfig":
|
||||
if configType.containing_type.full_name in ("meshtastic.LocalConfig", "LocalConfig"):
|
||||
p = admin_pb2.AdminMessage()
|
||||
p.get_config_request = msgIndex
|
||||
self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
|
||||
@@ -313,6 +318,8 @@ class Node:
|
||||
):
|
||||
channelSet.settings.append(c.settings)
|
||||
|
||||
if len(self.localConfig.ListFields()) == 0:
|
||||
self.requestConfig(self.localConfig.DESCRIPTOR.fields_by_name.get('lora'))
|
||||
channelSet.lora_config.CopyFrom(self.localConfig.lora)
|
||||
some_bytes = channelSet.SerializeToString()
|
||||
s = base64.urlsafe_b64encode(some_bytes).decode("ascii")
|
||||
@@ -569,6 +576,19 @@ class Node:
|
||||
onResponse = self.onAckNak
|
||||
return self._sendAdmin(p, onResponse=onResponse)
|
||||
|
||||
def enterDFUMode(self):
|
||||
"""Tell the node to enter DFU mode (NRF52)."""
|
||||
p = admin_pb2.AdminMessage()
|
||||
p.enter_dfu_mode_request = True
|
||||
logging.info(f"Telling node to enable DFU mode")
|
||||
|
||||
# If sending to a remote node, wait for ACK/NAK
|
||||
if self == self.iface.localNode:
|
||||
onResponse = None
|
||||
else:
|
||||
onResponse = self.onAckNak
|
||||
return self._sendAdmin(p, onResponse=onResponse)
|
||||
|
||||
def shutdown(self, secs: int = 10):
|
||||
"""Tell the node to shutdown."""
|
||||
p = admin_pb2.AdminMessage()
|
||||
@@ -588,9 +608,10 @@ class Node:
|
||||
p.get_device_metadata_request = True
|
||||
logging.info(f"Requesting device metadata")
|
||||
|
||||
return self._sendAdmin(
|
||||
self._sendAdmin(
|
||||
p, wantResponse=True, onResponse=self.onRequestGetMetadata
|
||||
)
|
||||
self.iface.waitForAckNak()
|
||||
|
||||
def factoryReset(self):
|
||||
"""Tell the node to factory reset."""
|
||||
@@ -605,6 +626,23 @@ class Node:
|
||||
onResponse = self.onAckNak
|
||||
return self._sendAdmin(p, onResponse=onResponse)
|
||||
|
||||
def removeNode(self, nodeId: Union[int, str]):
|
||||
"""Tell the node to remove a specific node by ID"""
|
||||
if isinstance(nodeId, str):
|
||||
if nodeId.startswith("!"):
|
||||
nodeId = int(nodeId[1:], 16)
|
||||
else:
|
||||
nodeId = int(nodeId)
|
||||
|
||||
p = admin_pb2.AdminMessage()
|
||||
p.remove_by_nodenum = nodeId
|
||||
|
||||
if self == self.iface.localNode:
|
||||
onResponse = None
|
||||
else:
|
||||
onResponse = self.onAckNak
|
||||
return self._sendAdmin(p, onResponse=onResponse)
|
||||
|
||||
def resetNodeDb(self):
|
||||
"""Tell the node to reset its list of nodes."""
|
||||
p = admin_pb2.AdminMessage()
|
||||
@@ -618,11 +656,43 @@ class Node:
|
||||
onResponse = self.onAckNak
|
||||
return self._sendAdmin(p, onResponse=onResponse)
|
||||
|
||||
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"""
|
||||
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:
|
||||
p.latitude_i = int(lat / 1e-7)
|
||||
elif isinstance(lat, int) and lat != 0:
|
||||
p.latitude_i = lat
|
||||
|
||||
if isinstance(lon, float) and lon != 0.0:
|
||||
p.longitude_i = int(lon / 1e-7)
|
||||
elif isinstance(lon, int) and lon != 0:
|
||||
p.longitude_i = lon
|
||||
|
||||
if alt != 0:
|
||||
p.altitude = alt
|
||||
|
||||
a = admin_pb2.AdminMessage()
|
||||
a.set_fixed_position.CopyFrom(p)
|
||||
return self._sendAdmin(a)
|
||||
|
||||
def removeFixedPosition(self):
|
||||
"""Tell the node to remove the fixed position and set the fixed position setting to false"""
|
||||
p = admin_pb2.AdminMessage()
|
||||
p.remove_fixed_position = True
|
||||
logging.info(f"Telling node to remove fixed position")
|
||||
|
||||
return self._sendAdmin(p)
|
||||
|
||||
def _fixupChannels(self):
|
||||
"""Fixup indexes and add disabled channels as needed"""
|
||||
|
||||
# Add extra disabled channels as needed
|
||||
# TODO: These 2 lines seem to not do anything.
|
||||
# This is needed because the protobufs will have index **missing** if the channel number is zero
|
||||
for index, ch in enumerate(self.channels):
|
||||
ch.index = index # fixup indexes
|
||||
|
||||
@@ -644,24 +714,30 @@ class Node:
|
||||
"""Handle the response packet for requesting device metadata getMetadata()"""
|
||||
logging.debug(f"onRequestGetMetadata() p:{p}")
|
||||
|
||||
if p["decoded"]["portnum"] == portnums_pb2.PortNum.Name(
|
||||
portnums_pb2.PortNum.ROUTING_APP
|
||||
):
|
||||
if "routing" in p["decoded"]:
|
||||
if p["decoded"]["routing"]["errorReason"] != "NONE":
|
||||
logging.warning(
|
||||
f'Metadata request failed, error reason: {p["decoded"]["routing"]["errorReason"]}'
|
||||
)
|
||||
self._timeout.expireTime = time.time() # Do not wait any longer
|
||||
return # Don't try to parse this routing message
|
||||
logging.debug(f"Retrying metadata request.")
|
||||
self.getMetadata()
|
||||
return
|
||||
print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
|
||||
self.iface._acknowledgment.receivedNak = True
|
||||
else:
|
||||
self.iface._acknowledgment.receivedAck = True
|
||||
if p["decoded"]["portnum"] == portnums_pb2.PortNum.Name(
|
||||
portnums_pb2.PortNum.ROUTING_APP
|
||||
):
|
||||
if p["decoded"]["routing"]["errorReason"] != "NONE":
|
||||
logging.warning(
|
||||
f'Metadata request failed, error reason: {p["decoded"]["routing"]["errorReason"]}'
|
||||
)
|
||||
self._timeout.expireTime = time.time() # Do not wait any longer
|
||||
return # Don't try to parse this routing message
|
||||
logging.debug(f"Retrying metadata request.")
|
||||
self.getMetadata()
|
||||
return
|
||||
|
||||
c = p["decoded"]["admin"]["raw"].get_device_metadata_response
|
||||
self._timeout.reset() # We made forward progress
|
||||
logging.debug(f"Received metadata {stripnl(c)}")
|
||||
print(f"\nfirmware_version: {c.firmware_version}")
|
||||
print(f"device_state_version: {c.device_state_version}")
|
||||
c = p["decoded"]["admin"]["raw"].get_device_metadata_response
|
||||
self._timeout.reset() # We made forward progress
|
||||
logging.debug(f"Received metadata {stripnl(c)}")
|
||||
print(f"\nfirmware_version: {c.firmware_version}")
|
||||
print(f"device_state_version: {c.device_state_version}")
|
||||
|
||||
def onResponseRequestChannel(self, p):
|
||||
"""Handle the response packet for requesting a channel _requestChannel()"""
|
||||
@@ -694,9 +770,6 @@ class Node:
|
||||
|
||||
self.channels = self.partialChannels
|
||||
self._fixupChannels()
|
||||
|
||||
# FIXME, the following should only be called after we have settings and channels
|
||||
self.iface._connected() # Tell everyone else we are ready to go
|
||||
else:
|
||||
self._requestChannel(index + 1)
|
||||
|
||||
@@ -742,9 +815,9 @@ class Node:
|
||||
def _sendAdmin(
|
||||
self,
|
||||
p: admin_pb2.AdminMessage,
|
||||
wantResponse=True,
|
||||
wantResponse: bool=True,
|
||||
onResponse=None,
|
||||
adminIndex=0,
|
||||
adminIndex: int=0,
|
||||
):
|
||||
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
|
||||
|
||||
|
||||
@@ -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*\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=30
|
||||
_PORTNUM._serialized_end=555
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
0
meshtastic/protobuf/__init__.py
Normal file
0
meshtastic/protobuf/__init__.py
Normal file
39
meshtastic/protobuf/admin_pb2.py
Normal file
39
meshtastic/protobuf/admin_pb2.py
Normal file
@@ -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\"\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)
|
||||
_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=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)
|
||||
578
meshtastic/protobuf/admin_pb2.pyi
Normal file
578
meshtastic/protobuf/admin_pb2.pyi
Normal file
@@ -0,0 +1,578 @@
|
||||
"""
|
||||
@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_SCALE_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_scale: builtins.int
|
||||
"""
|
||||
Set zero and offset for scale chips
|
||||
"""
|
||||
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_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 = ...,
|
||||
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", "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
|
||||
|
||||
@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
|
||||
28
meshtastic/protobuf/apponly_pb2.py
Normal file
28
meshtastic/protobuf/apponly_pb2.py
Normal file
@@ -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)
|
||||
52
meshtastic/protobuf/apponly_pb2.pyi
Normal file
52
meshtastic/protobuf/apponly_pb2.pyi
Normal file
@@ -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
|
||||
40
meshtastic/protobuf/atak_pb2.py
Normal file
40
meshtastic/protobuf/atak_pb2.py
Normal file
@@ -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)
|
||||
470
meshtastic/protobuf/atak_pb2.pyi
Normal file
470
meshtastic/protobuf/atak_pb2.pyi
Normal file
@@ -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
|
||||
<status battery='100' />
|
||||
"""
|
||||
|
||||
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
|
||||
<contact endpoint='0.0.0.0:4242:tcp' phone='+12345678' callsign='FALKE'/>
|
||||
"""
|
||||
|
||||
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
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/cannedmessages.proto
|
||||
# source: meshtastic/protobuf/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
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/cannedmessages.proto\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBn\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.cannedmessages_pb2', globals())
|
||||
_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'
|
||||
_CANNEDMESSAGEMODULECONFIG._serialized_start=35
|
||||
_CANNEDMESSAGEMODULECONFIG._serialized_end=80
|
||||
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_start=65
|
||||
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_end=110
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
33
meshtastic/protobuf/cannedmessages_pb2.pyi
Normal file
33
meshtastic/protobuf/cannedmessages_pb2.pyi
Normal file
@@ -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
|
||||
34
meshtastic/protobuf/channel_pb2.py
Normal file
34
meshtastic/protobuf/channel_pb2.py
Normal file
@@ -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)
|
||||
234
meshtastic/protobuf/channel_pb2.pyi
Normal file
234
meshtastic/protobuf/channel_pb2.pyi
Normal file
@@ -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
|
||||
27
meshtastic/protobuf/clientonly_pb2.py
Normal file
27
meshtastic/protobuf/clientonly_pb2.py
Normal file
@@ -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)
|
||||
74
meshtastic/protobuf/clientonly_pb2.pyi
Normal file
74
meshtastic/protobuf/clientonly_pb2.pyi
Normal file
@@ -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
|
||||
72
meshtastic/protobuf/config_pb2.py
Normal file
72
meshtastic/protobuf/config_pb2.py
Normal file
File diff suppressed because one or more lines are too long
1590
meshtastic/protobuf/config_pb2.pyi
Normal file
1590
meshtastic/protobuf/config_pb2.pyi
Normal file
File diff suppressed because it is too large
Load Diff
36
meshtastic/protobuf/connection_status_pb2.py
Normal file
36
meshtastic/protobuf/connection_status_pb2.py
Normal file
@@ -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)
|
||||
228
meshtastic/protobuf/connection_status_pb2.pyi
Normal file
228
meshtastic/protobuf/connection_status_pb2.pyi
Normal file
@@ -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
|
||||
46
meshtastic/protobuf/deviceonly_pb2.py
Normal file
46
meshtastic/protobuf/deviceonly_pb2.py
Normal file
@@ -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<meshtastic_NodeInfoLite>\"N\n\x0b\x43hannelFile\x12.\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\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\x08<vector>b\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_pb2', _globals)
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
|
||||
_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<meshtastic_NodeInfoLite>'
|
||||
_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)
|
||||
400
meshtastic/protobuf/deviceonly_pb2.pyi
Normal file
400
meshtastic/protobuf/deviceonly_pb2.pyi
Normal file
@@ -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
|
||||
30
meshtastic/protobuf/localonly_pb2.py
Normal file
30
meshtastic/protobuf/localonly_pb2.py
Normal file
@@ -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)
|
||||
220
meshtastic/protobuf/localonly_pb2.pyi
Normal file
220
meshtastic/protobuf/localonly_pb2.pyi
Normal file
@@ -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
|
||||
98
meshtastic/protobuf/mesh_pb2.py
Normal file
98
meshtastic/protobuf/mesh_pb2.py
Normal file
File diff suppressed because one or more lines are too long
2568
meshtastic/protobuf/mesh_pb2.pyi
Normal file
2568
meshtastic/protobuf/mesh_pb2.pyi
Normal file
File diff suppressed because it is too large
Load Diff
66
meshtastic/protobuf/module_config_pb2.py
Normal file
66
meshtastic/protobuf/module_config_pb2.py
Normal file
File diff suppressed because one or more lines are too long
1200
meshtastic/protobuf/module_config_pb2.pyi
Normal file
1200
meshtastic/protobuf/module_config_pb2.pyi
Normal file
File diff suppressed because it is too large
Load Diff
30
meshtastic/protobuf/mqtt_pb2.py
Normal file
30
meshtastic/protobuf/mqtt_pb2.py
Normal file
@@ -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)
|
||||
148
meshtastic/protobuf/mqtt_pb2.pyi
Normal file
148
meshtastic/protobuf/mqtt_pb2.pyi
Normal file
@@ -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
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/paxcount.proto
|
||||
# source: meshtastic/protobuf/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
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19meshtastic/paxcount.proto\"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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.paxcount_pb2', globals())
|
||||
_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'
|
||||
_PAXCOUNT._serialized_start=29
|
||||
_PAXCOUNT._serialized_end=82
|
||||
_globals['_PAXCOUNT']._serialized_start=59
|
||||
_globals['_PAXCOUNT']._serialized_end=112
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
45
meshtastic/protobuf/paxcount_pb2.pyi
Normal file
45
meshtastic/protobuf/paxcount_pb2.pyi
Normal file
@@ -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
|
||||
26
meshtastic/protobuf/portnums_pb2.py
Normal file
26
meshtastic/protobuf/portnums_pb2.py
Normal file
@@ -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)
|
||||
370
meshtastic/protobuf/portnums_pb2.pyi
Normal file
370
meshtastic/protobuf/portnums_pb2.pyi
Normal file
@@ -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
|
||||
28
meshtastic/protobuf/remote_hardware_pb2.py
Normal file
28
meshtastic/protobuf/remote_hardware_pb2.py
Normal file
@@ -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)
|
||||
126
meshtastic/protobuf/remote_hardware_pb2.pyi
Normal file
126
meshtastic/protobuf/remote_hardware_pb2.pyi
Normal file
@@ -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
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/rtttl.proto
|
||||
# source: meshtastic/protobuf/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
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/rtttl.proto\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBf\n\x13\x63om.geeksville.meshB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.rtttl_pb2', globals())
|
||||
_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'
|
||||
_RTTTLCONFIG._serialized_start=26
|
||||
_RTTTLCONFIG._serialized_end=57
|
||||
_globals['_RTTTLCONFIG']._serialized_start=56
|
||||
_globals['_RTTTLCONFIG']._serialized_end=87
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
33
meshtastic/protobuf/rtttl_pb2.pyi
Normal file
33
meshtastic/protobuf/rtttl_pb2.pyi
Normal file
@@ -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
|
||||
34
meshtastic/protobuf/storeforward_pb2.py
Normal file
34
meshtastic/protobuf/storeforward_pb2.py
Normal file
@@ -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)
|
||||
345
meshtastic/protobuf/storeforward_pb2.pyi
Normal file
345
meshtastic/protobuf/storeforward_pb2.pyi
Normal file
@@ -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
|
||||
38
meshtastic/protobuf/telemetry_pb2.py
Normal file
38
meshtastic/protobuf/telemetry_pb2.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- 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\"\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)
|
||||
_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=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=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)
|
||||
618
meshtastic/protobuf/telemetry_pb2.pyi
Normal file
618
meshtastic/protobuf/telemetry_pb2.pyi
Normal file
@@ -0,0 +1,618 @@
|
||||
"""
|
||||
@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)
|
||||
"""
|
||||
NAU7802: _TelemetrySensorType.ValueType # 25
|
||||
"""
|
||||
NAU7802 Scale Chip or compatible
|
||||
"""
|
||||
|
||||
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)
|
||||
"""
|
||||
NAU7802: TelemetrySensorType.ValueType # 25
|
||||
"""
|
||||
NAU7802 Scale Chip or compatible
|
||||
"""
|
||||
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
|
||||
WEIGHT_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
|
||||
"""
|
||||
weight: builtins.float
|
||||
"""
|
||||
Weight in KG
|
||||
"""
|
||||
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 = ...,
|
||||
) -> 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
|
||||
|
||||
@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
|
||||
|
||||
@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
|
||||
28
meshtastic/protobuf/xmodem_pb2.py
Normal file
28
meshtastic/protobuf/xmodem_pb2.py
Normal file
@@ -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)
|
||||
67
meshtastic/protobuf/xmodem_pb2.pyi
Normal file
67
meshtastic/protobuf/xmodem_pb2.pyi
Normal file
@@ -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
|
||||
@@ -2,9 +2,9 @@
|
||||
"""
|
||||
import logging
|
||||
|
||||
from pubsub import pub
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -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\"\xcb\x01\n\x0fHardwareMessage\x12#\n\x04type\x18\x01 \x01(\x0e\x32\x15.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\x63\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_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=37
|
||||
_HARDWAREMESSAGE._serialized_end=240
|
||||
_HARDWAREMESSAGE_TYPE._serialized_start=132
|
||||
_HARDWAREMESSAGE_TYPE._serialized_end=240
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -4,7 +4,9 @@ import logging
|
||||
import platform
|
||||
import time
|
||||
|
||||
import serial
|
||||
from typing import Optional
|
||||
|
||||
import serial # type: ignore[import-untyped]
|
||||
|
||||
import meshtastic.util
|
||||
from meshtastic.stream_interface import StreamInterface
|
||||
@@ -16,7 +18,7 @@ if platform.system() != "Windows":
|
||||
class SerialInterface(StreamInterface):
|
||||
"""Interface class for meshtastic devices over a serial link"""
|
||||
|
||||
def __init__(self, devPath=None, debugOut=None, noProto=False, connectNow=True):
|
||||
def __init__(self, devPath: Optional[str]=None, debugOut=None, noProto=False, connectNow=True, noNodes: bool=False):
|
||||
"""Constructor, opens a connection to a specified serial port, or if unspecified try to
|
||||
find one Meshtastic device by probing
|
||||
|
||||
@@ -26,7 +28,7 @@ class SerialInterface(StreamInterface):
|
||||
"""
|
||||
self.noProto = noProto
|
||||
|
||||
self.devPath = devPath
|
||||
self.devPath: Optional[str] = devPath
|
||||
|
||||
if self.devPath is None:
|
||||
ports = meshtastic.util.findPorts(True)
|
||||
@@ -60,7 +62,7 @@ class SerialInterface(StreamInterface):
|
||||
time.sleep(0.1)
|
||||
|
||||
StreamInterface.__init__(
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes
|
||||
)
|
||||
|
||||
def close(self):
|
||||
|
||||
@@ -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\"\xf0\x06\n\x0fStoreAndForward\x12,\n\x02rr\x18\x01 \x01(\x0e\x32 .StoreAndForward.RequestResponse\x12,\n\x05stats\x18\x02 \x01(\x0b\x32\x1b.StoreAndForward.StatisticsH\x00\x12+\n\x07history\x18\x03 \x01(\x0b\x32\x18.StoreAndForward.HistoryH\x00\x12/\n\theartbeat\x18\x04 \x01(\x0b\x32\x1a.StoreAndForward.HeartbeatH\x00\x12\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=34
|
||||
_STOREANDFORWARD._serialized_end=914
|
||||
_STOREANDFORWARD_STATISTICS._serialized_start=256
|
||||
_STOREANDFORWARD_STATISTICS._serialized_end=461
|
||||
_STOREANDFORWARD_HISTORY._serialized_start=463
|
||||
_STOREANDFORWARD_HISTORY._serialized_end=536
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_start=538
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_end=584
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=587
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=903
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -5,7 +5,7 @@ import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
import serial
|
||||
import serial # type: ignore[import-untyped]
|
||||
|
||||
from meshtastic.mesh_interface import MeshInterface
|
||||
from meshtastic.util import is_windows11, stripnl
|
||||
@@ -19,7 +19,7 @@ MAX_TO_FROM_RADIO_SIZE = 512
|
||||
class StreamInterface(MeshInterface):
|
||||
"""Interface class for meshtastic devices over a stream link (serial, TCP, etc)"""
|
||||
|
||||
def __init__(self, debugOut=None, noProto=False, connectNow=True):
|
||||
def __init__(self, debugOut=None, noProto=False, connectNow=True, noNodes=False):
|
||||
"""Constructor, opens a connection to self.stream
|
||||
|
||||
Keyword Arguments:
|
||||
@@ -43,7 +43,7 @@ class StreamInterface(MeshInterface):
|
||||
# FIXME, figure out why daemon=True causes reader thread to exit too early
|
||||
self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True)
|
||||
|
||||
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
|
||||
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes)
|
||||
|
||||
# Start the reader thread after superclass constructor completes init
|
||||
if connectNow:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
import logging
|
||||
import socket
|
||||
from typing import AnyStr
|
||||
from typing import Optional
|
||||
|
||||
from meshtastic.stream_interface import StreamInterface
|
||||
|
||||
@@ -12,11 +12,12 @@ class TCPInterface(StreamInterface):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hostname: AnyStr,
|
||||
hostname: str,
|
||||
debugOut=None,
|
||||
noProto=False,
|
||||
connectNow=True,
|
||||
portNumber=4403,
|
||||
noNodes:bool=False,
|
||||
):
|
||||
"""Constructor, opens a connection to a specified IP address/hostname
|
||||
|
||||
@@ -30,15 +31,15 @@ class TCPInterface(StreamInterface):
|
||||
self.portNumber = portNumber
|
||||
|
||||
if connectNow:
|
||||
logging.debug(f"Connecting to {hostname}")
|
||||
logging.debug(f"Connecting to {hostname}") # type: ignore[str-bytes-safe]
|
||||
server_address = (hostname, portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock
|
||||
self.socket: Optional[socket.socket] = sock
|
||||
else:
|
||||
self.socket = None
|
||||
|
||||
StreamInterface.__init__(
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes
|
||||
)
|
||||
|
||||
def _socket_shutdown(self):
|
||||
|
||||
@@ -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\"i\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\"\x9b\x01\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\"\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\"\xdd\x01\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12(\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x0e.DeviceMetricsH\x00\x12\x32\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x13.EnvironmentMetricsH\x00\x12\x31\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32\x12.AirQualityMetricsH\x00\x12&\n\rpower_metrics\x18\x05 \x01(\x0b\x32\r.PowerMetricsH\x00\x42\t\n\x07variant*\xe0\x01\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\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=985
|
||||
_TELEMETRYSENSORTYPE._serialized_end=1209
|
||||
_DEVICEMETRICS._serialized_start=30
|
||||
_DEVICEMETRICS._serialized_end=135
|
||||
_ENVIRONMENTMETRICS._serialized_start=138
|
||||
_ENVIRONMENTMETRICS._serialized_end=293
|
||||
_POWERMETRICS._serialized_start=296
|
||||
_POWERMETRICS._serialized_end=436
|
||||
_AIRQUALITYMETRICS._serialized_start=439
|
||||
_AIRQUALITYMETRICS._serialized_end=758
|
||||
_TELEMETRY._serialized_start=761
|
||||
_TELEMETRY._serialized_end=982
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -6,11 +6,11 @@ import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from dotmap import DotMap
|
||||
from pubsub import pub
|
||||
from dotmap import DotMap # type: ignore[import-untyped]
|
||||
from pubsub import pub # type: ignore[import-untyped]
|
||||
|
||||
import meshtastic.util
|
||||
from meshtastic.__init__ import BROADCAST_NUM
|
||||
from meshtastic import BROADCAST_NUM
|
||||
from meshtastic.serial_interface import SerialInterface
|
||||
from meshtastic.tcp_interface import TCPInterface
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from meshtastic.__main__ import Globals
|
||||
from meshtastic import mt_config
|
||||
|
||||
from ..mesh_interface import MeshInterface
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def reset_globals():
|
||||
"""Fixture to reset globals."""
|
||||
def reset_mt_config():
|
||||
"""Fixture to reset mt_config."""
|
||||
parser = None
|
||||
parser = argparse.ArgumentParser()
|
||||
Globals.getInstance().reset()
|
||||
Globals.getInstance().set_parser(parser)
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
mt_config.reset()
|
||||
mt_config.parser = parser
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
"""Meshtastic unit tests for globals.py
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from ..globals import Globals
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_globals_get_instaance():
|
||||
"""Test that we can instantiate a Globals instance"""
|
||||
ourglobals = Globals.getInstance()
|
||||
ourglobals2 = Globals.getInstance()
|
||||
assert ourglobals == ourglobals2
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_globals_there_can_be_only_one():
|
||||
"""Test that we can cannot create two Globals instances"""
|
||||
# if we have an instance, delete it
|
||||
Globals.getInstance()
|
||||
with pytest.raises(Exception) as pytest_wrapped_e:
|
||||
# try to create another instance
|
||||
Globals()
|
||||
assert pytest_wrapped_e.type == Exception
|
||||
@@ -6,9 +6,8 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from meshtastic.__init__ import _onNodeInfoReceive, _onPositionReceive, _onTextReceive
|
||||
from meshtastic import _onNodeInfoReceive, _onPositionReceive, _onTextReceive, mt_config
|
||||
|
||||
from ..globals import Globals
|
||||
from ..serial_interface import SerialInterface
|
||||
|
||||
|
||||
@@ -16,7 +15,7 @@ from ..serial_interface import SerialInterface
|
||||
def test_init_onTextReceive_with_exception(caplog):
|
||||
"""Test _onTextReceive"""
|
||||
args = MagicMock()
|
||||
Globals.getInstance().set_args(args)
|
||||
mt_config.args = args
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
packet = {}
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
@@ -29,7 +28,7 @@ def test_init_onTextReceive_with_exception(caplog):
|
||||
def test_init_onPositionReceive(caplog):
|
||||
"""Test _onPositionReceive"""
|
||||
args = MagicMock()
|
||||
Globals.getInstance().set_args(args)
|
||||
mt_config.args = args
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
packet = {"from": "foo", "decoded": {"position": {}}}
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
@@ -41,11 +40,11 @@ def test_init_onPositionReceive(caplog):
|
||||
def test_init_onNodeInfoReceive(caplog, iface_with_nodes):
|
||||
"""Test _onNodeInfoReceive"""
|
||||
args = MagicMock()
|
||||
Globals.getInstance().set_args(args)
|
||||
mt_config.args = args
|
||||
iface = iface_with_nodes
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
packet = {
|
||||
"from": "foo",
|
||||
"from": 4808675309,
|
||||
"decoded": {
|
||||
"user": {
|
||||
"id": "bar",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,11 @@ import re
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
from .. import mesh_pb2
|
||||
from ..__init__ import BROADCAST_ADDR, LOCAL_ADDR
|
||||
from ..mesh_interface import MeshInterface
|
||||
from ..protobuf import mesh_pb2, config_pb2
|
||||
from .. import BROADCAST_ADDR, LOCAL_ADDR
|
||||
from ..mesh_interface import MeshInterface, _timeago
|
||||
from ..node import Node
|
||||
|
||||
# TODO
|
||||
@@ -17,16 +18,17 @@ from ..util import Timeout
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_MeshInterface(capsys):
|
||||
"""Test that we can instantiate a MeshInterface"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
|
||||
nodes = {
|
||||
"!9388f81c": {
|
||||
"num": 2475227164,
|
||||
NODE_ID = "!9388f81c"
|
||||
NODE_NUM = 2475227164
|
||||
node = {
|
||||
"num": NODE_NUM,
|
||||
"user": {
|
||||
"id": "!9388f81c",
|
||||
"id": NODE_ID,
|
||||
"longName": "Unknown f81c",
|
||||
"shortName": "?1C",
|
||||
"macaddr": "RBeTiPgc",
|
||||
@@ -35,14 +37,16 @@ def test_MeshInterface(capsys):
|
||||
"position": {},
|
||||
"lastHeard": 1640204888,
|
||||
}
|
||||
}
|
||||
|
||||
iface.nodesByNum = {2475227164: nodes["!9388f81c"]}
|
||||
iface.nodes = nodes
|
||||
|
||||
iface.nodes = {NODE_ID: node}
|
||||
iface.nodesByNum = {NODE_NUM: node}
|
||||
|
||||
myInfo = MagicMock()
|
||||
iface.myInfo = myInfo
|
||||
|
||||
iface.localNode.localConfig.lora.CopyFrom(config_pb2.Config.LoRaConfig())
|
||||
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.showNodes()
|
||||
@@ -58,7 +62,7 @@ def test_MeshInterface(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getMyUser(iface_with_nodes):
|
||||
"""Test getMyUser()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -69,7 +73,7 @@ def test_getMyUser(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getLongName(iface_with_nodes):
|
||||
"""Test getLongName()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -79,7 +83,7 @@ def test_getLongName(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getShortName(iface_with_nodes):
|
||||
"""Test getShortName()."""
|
||||
iface = iface_with_nodes
|
||||
@@ -89,7 +93,7 @@ def test_getShortName(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handlePacketFromRadio_no_from(capsys):
|
||||
"""Test _handlePacketFromRadio with no 'from' in the mesh packet."""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -101,7 +105,7 @@ def test_handlePacketFromRadio_no_from(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handlePacketFromRadio_with_a_portnum(caplog):
|
||||
"""Test _handlePacketFromRadio with a portnum
|
||||
Since we have an attribute called 'from', we cannot simply 'set' it.
|
||||
@@ -117,7 +121,7 @@ def test_handlePacketFromRadio_with_a_portnum(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handlePacketFromRadio_no_portnum(caplog):
|
||||
"""Test _handlePacketFromRadio without a portnum"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -129,7 +133,7 @@ def test_handlePacketFromRadio_no_portnum(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getNode_with_local():
|
||||
"""Test getNode"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -138,7 +142,7 @@ def test_getNode_with_local():
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getNode_not_local(caplog):
|
||||
"""Test getNode not local"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -151,7 +155,7 @@ def test_getNode_not_local(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getNode_not_local_timeout(capsys):
|
||||
"""Test getNode not local, simulate timeout"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -168,7 +172,7 @@ def test_getNode_not_local_timeout(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPosition(caplog):
|
||||
"""Test sendPosition"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -180,7 +184,7 @@ def test_sendPosition(caplog):
|
||||
|
||||
# TODO
|
||||
# @pytest.mark.unit
|
||||
# @pytest.mark.usefixtures("reset_globals")
|
||||
# @pytest.mark.usefixtures("reset_mt_config")
|
||||
# def test_close_with_heartbeatTimer(caplog):
|
||||
# """Test close() with heartbeatTimer"""
|
||||
# iface = MeshInterface(noProto=True)
|
||||
@@ -198,7 +202,7 @@ def test_sendPosition(caplog):
|
||||
|
||||
# TODO
|
||||
# @pytest.mark.unit
|
||||
# @pytest.mark.usefixtures("reset_globals")
|
||||
# @pytest.mark.usefixtures("reset_mt_config")
|
||||
# def test_handleFromRadio_empty_payload(caplog):
|
||||
# """Test _handleFromRadio"""
|
||||
# iface = MeshInterface(noProto=True)
|
||||
@@ -209,7 +213,7 @@ def test_sendPosition(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handleFromRadio_with_my_info(caplog):
|
||||
"""Test _handleFromRadio with my_info"""
|
||||
# Note: I captured the '--debug --info' for the bytes below.
|
||||
@@ -234,7 +238,7 @@ def test_handleFromRadio_with_my_info(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handleFromRadio_with_node_info(caplog, capsys):
|
||||
"""Test _handleFromRadio with node_info"""
|
||||
# Note: I captured the '--debug --info' for the bytes below.
|
||||
@@ -270,7 +274,7 @@ def test_handleFromRadio_with_node_info(caplog, capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handleFromRadio_with_node_info_tbeam1(caplog, capsys):
|
||||
"""Test _handleFromRadio with node_info"""
|
||||
# Note: Captured the '--debug --info' for the bytes below.
|
||||
@@ -294,7 +298,7 @@ def test_handleFromRadio_with_node_info_tbeam1(caplog, capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_handleFromRadio_with_node_info_tbeam_with_bad_data(caplog):
|
||||
"""Test _handleFromRadio with node_info with some bad data (issue#172) - ensure we do not throw exception"""
|
||||
# Note: Captured the '--debug --info' for the bytes below.
|
||||
@@ -306,7 +310,7 @@ def test_handleFromRadio_with_node_info_tbeam_with_bad_data(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_MeshInterface_sendToRadioImpl(caplog):
|
||||
"""Test _sendToRadioImp()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -317,7 +321,7 @@ def test_MeshInterface_sendToRadioImpl(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_MeshInterface_sendToRadio_no_proto(caplog):
|
||||
"""Test sendToRadio()"""
|
||||
iface = MeshInterface()
|
||||
@@ -328,7 +332,7 @@ def test_MeshInterface_sendToRadio_no_proto(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendData_too_long(caplog):
|
||||
"""Test when data payload is too big"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -353,7 +357,7 @@ def test_sendData_too_long(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendData_unknown_app(capsys):
|
||||
"""Test sendData when unknown app"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -367,7 +371,7 @@ def test_sendData_unknown_app(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPosition_with_a_position(caplog):
|
||||
"""Test sendPosition when lat/long/alt"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -379,7 +383,7 @@ def test_sendPosition_with_a_position(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_no_destination(capsys):
|
||||
"""Test _sendPacket()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -393,7 +397,7 @@ def test_sendPacket_with_no_destination(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_as_int(caplog):
|
||||
"""Test _sendPacket() with int as a destination"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -404,7 +408,7 @@ def test_sendPacket_with_destination_as_int(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_starting_with_a_bang(caplog):
|
||||
"""Test _sendPacket() with int as a destination"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -415,7 +419,7 @@ def test_sendPacket_with_destination_starting_with_a_bang(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_as_BROADCAST_ADDR(caplog):
|
||||
"""Test _sendPacket() with BROADCAST_ADDR as a destination"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -426,7 +430,7 @@ def test_sendPacket_with_destination_as_BROADCAST_ADDR(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_as_LOCAL_ADDR_no_myInfo(capsys):
|
||||
"""Test _sendPacket() with LOCAL_ADDR as a destination with no myInfo"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -441,7 +445,7 @@ def test_sendPacket_with_destination_as_LOCAL_ADDR_no_myInfo(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_as_LOCAL_ADDR_with_myInfo(caplog):
|
||||
"""Test _sendPacket() with LOCAL_ADDR as a destination with myInfo"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -455,7 +459,7 @@ def test_sendPacket_with_destination_as_LOCAL_ADDR_with_myInfo(caplog):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_is_blank_with_nodes(capsys, iface_with_nodes):
|
||||
"""Test _sendPacket() with '' as a destination with myInfo"""
|
||||
iface = iface_with_nodes
|
||||
@@ -470,7 +474,7 @@ def test_sendPacket_with_destination_is_blank_with_nodes(capsys, iface_with_node
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_sendPacket_with_destination_is_blank_without_nodes(caplog, iface_with_nodes):
|
||||
"""Test _sendPacket() with '' as a destination with myInfo"""
|
||||
iface = iface_with_nodes
|
||||
@@ -482,7 +486,7 @@ def test_sendPacket_with_destination_is_blank_without_nodes(caplog, iface_with_n
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getMyNodeInfo():
|
||||
"""Test getMyNodeInfo()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -497,7 +501,7 @@ def test_getMyNodeInfo():
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_generatePacketId(capsys):
|
||||
"""Test _generatePacketId() when no currentPacketId (not connected)"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -515,7 +519,7 @@ def test_generatePacketId(capsys):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_fixupPosition_empty_pos():
|
||||
"""Test _fixupPosition()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -525,7 +529,7 @@ def test_fixupPosition_empty_pos():
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_fixupPosition_no_changes_needed():
|
||||
"""Test _fixupPosition()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -535,7 +539,7 @@ def test_fixupPosition_no_changes_needed():
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_fixupPosition():
|
||||
"""Test _fixupPosition()"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
@@ -550,7 +554,7 @@ def test_fixupPosition():
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_nodeNumToId(iface_with_nodes):
|
||||
"""Test _nodeNumToId()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -560,7 +564,7 @@ def test_nodeNumToId(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_nodeNumToId_not_found(iface_with_nodes):
|
||||
"""Test _nodeNumToId()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -570,7 +574,7 @@ def test_nodeNumToId_not_found(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_nodeNumToId_to_all(iface_with_nodes):
|
||||
"""Test _nodeNumToId()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -580,17 +584,17 @@ def test_nodeNumToId_to_all(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getOrCreateByNum_minimal(iface_with_nodes):
|
||||
"""Test _getOrCreateByNum()"""
|
||||
iface = iface_with_nodes
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
tmp = iface._getOrCreateByNum(123)
|
||||
assert tmp == {"num": 123}
|
||||
assert tmp == {"num": 123, "user": {"hwModel": "UNSET", "id": "!0000007b", "shortName": "007b", "longName": "Meshtastic 007b"}}
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getOrCreateByNum_not_found(iface_with_nodes):
|
||||
"""Test _getOrCreateByNum()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -601,7 +605,7 @@ def test_getOrCreateByNum_not_found(iface_with_nodes):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_getOrCreateByNum(iface_with_nodes):
|
||||
"""Test _getOrCreateByNum()"""
|
||||
iface = iface_with_nodes
|
||||
@@ -682,3 +686,21 @@ 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():
|
||||
"""Test that the _timeago function returns sane values"""
|
||||
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"
|
||||
|
||||
@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)
|
||||
|
||||
@@ -6,8 +6,8 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
# from ..admin_pb2 import AdminMessage
|
||||
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
|
||||
@@ -19,21 +19,26 @@ from ..mesh_interface import MeshInterface
|
||||
# from ..util import Timeout
|
||||
|
||||
|
||||
# TODO
|
||||
# @pytest.mark.unit
|
||||
# def test_node(capsys):
|
||||
# """Test that we can instantiate a Node"""
|
||||
# anode = Node('foo', 'bar')
|
||||
# radioConfig = RadioConfig()
|
||||
# anode.radioConfig = radioConfig
|
||||
# anode.showChannels()
|
||||
# anode.showInfo()
|
||||
# out, err = capsys.readouterr()
|
||||
# assert re.search(r'Preferences', out)
|
||||
# assert re.search(r'Channels', out)
|
||||
# assert re.search(r'Primary channel URL', out)
|
||||
# assert err == ''
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_node(capsys):
|
||||
"""Test that we can instantiate a Node"""
|
||||
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)
|
||||
lc = localonly_pb2.LocalConfig()
|
||||
anode.localConfig = lc
|
||||
lc.lora.CopyFrom(config_pb2.Config.LoRaConfig())
|
||||
anode.moduleConfig = localonly_pb2.LocalModuleConfig()
|
||||
anode.showInfo()
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Preferences', out)
|
||||
assert re.search(r'Module preferences', out)
|
||||
assert re.search(r'Channels', out)
|
||||
assert re.search(r'Primary channel URL', out)
|
||||
assert not re.search(r'remote node', out)
|
||||
assert err == ''
|
||||
|
||||
# TODO
|
||||
# @pytest.mark.unit
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import mock_open, patch
|
||||
import pytest
|
||||
|
||||
from ..serial_interface import SerialInterface
|
||||
from ..protobuf import config_pb2
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@@ -20,6 +21,7 @@ def test_SerialInterface_single_port(
|
||||
):
|
||||
"""Test that we can instantiate a SerialInterface with a single port"""
|
||||
iface = SerialInterface(noProto=True)
|
||||
iface.localNode.localConfig.lora.CopyFrom(config_pb2.Config.LoRaConfig())
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.close()
|
||||
|
||||
@@ -20,7 +20,7 @@ def test_StreamInterface():
|
||||
|
||||
# Note: This takes a bit, so moving from unit to slow
|
||||
@pytest.mark.unitslow
|
||||
@pytest.mark.usefixtures("reset_globals")
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_StreamInterface_with_noProto(caplog):
|
||||
"""Test that we can instantiate a StreamInterface based on nonProto
|
||||
and we can read/write bytes from a mocked stream
|
||||
@@ -41,7 +41,7 @@ def test_StreamInterface_with_noProto(caplog):
|
||||
### Tip: If you want to see the print output, run with '-s' flag:
|
||||
### pytest -s meshtastic/tests/test_stream_interface.py::test_sendToRadioImpl
|
||||
# @pytest.mark.unitslow
|
||||
# @pytest.mark.usefixtures("reset_globals")
|
||||
# @pytest.mark.usefixtures("reset_mt_config")
|
||||
# def test_sendToRadioImpl(caplog):
|
||||
# """Test _sendToRadioImpl()"""
|
||||
#
|
||||
|
||||
@@ -5,6 +5,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from ..protobuf import config_pb2
|
||||
from ..tcp_interface import TCPInterface
|
||||
|
||||
|
||||
@@ -13,6 +14,7 @@ def test_TCPInterface(capsys):
|
||||
"""Test that we can instantiate a TCPInterface"""
|
||||
with patch("socket.socket") as mock_socket:
|
||||
iface = TCPInterface(hostname="localhost", noProto=True)
|
||||
iface.localNode.localConfig.lora.CopyFrom(config_pb2.Config.LoRaConfig())
|
||||
iface.myConnect()
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""Meshtastic unit tests for tunnel.py"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
@@ -7,7 +6,8 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from ..globals import Globals
|
||||
from meshtastic import mt_config
|
||||
|
||||
from ..tcp_interface import TCPInterface
|
||||
from ..tunnel import Tunnel, onTunnelReceive
|
||||
|
||||
@@ -51,7 +51,7 @@ def test_Tunnel_with_interface(mock_platform_system, caplog, iface_with_nodes):
|
||||
with caplog.at_level(logging.WARNING):
|
||||
with patch("socket.socket"):
|
||||
tun = Tunnel(iface)
|
||||
assert tun == Globals.getInstance().get_tunnelInstance()
|
||||
assert tun == mt_config.tunnelInstance
|
||||
iface.close()
|
||||
assert re.search(r"Not creating a TapDevice()", caplog.text, re.MULTILINE)
|
||||
assert re.search(r"Not starting TUN reader", caplog.text, re.MULTILINE)
|
||||
@@ -65,7 +65,7 @@ def test_onTunnelReceive_from_ourselves(mock_platform_system, caplog, iface_with
|
||||
iface = iface_with_nodes
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
sys.argv = [""]
|
||||
Globals.getInstance().set_args(sys.argv)
|
||||
mt_config.args = sys.argv
|
||||
packet = {"decoded": {"payload": "foo"}, "from": 2475227164}
|
||||
a_mock = MagicMock()
|
||||
a_mock.return_value = "Linux"
|
||||
@@ -73,7 +73,7 @@ def test_onTunnelReceive_from_ourselves(mock_platform_system, caplog, iface_with
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
with patch("socket.socket"):
|
||||
tun = Tunnel(iface)
|
||||
Globals.getInstance().set_tunnelInstance(tun)
|
||||
mt_config.tunnelInstance = tun
|
||||
onTunnelReceive(packet, iface)
|
||||
assert re.search(r"in onTunnelReceive", caplog.text, re.MULTILINE)
|
||||
assert re.search(r"Ignoring message we sent", caplog.text, re.MULTILINE)
|
||||
@@ -88,7 +88,7 @@ def test_onTunnelReceive_from_someone_else(
|
||||
iface = iface_with_nodes
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
sys.argv = [""]
|
||||
Globals.getInstance().set_args(sys.argv)
|
||||
mt_config.args = sys.argv
|
||||
packet = {"decoded": {"payload": "foo"}, "from": 123}
|
||||
a_mock = MagicMock()
|
||||
a_mock.return_value = "Linux"
|
||||
@@ -96,7 +96,7 @@ def test_onTunnelReceive_from_someone_else(
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
with patch("socket.socket"):
|
||||
tun = Tunnel(iface)
|
||||
Globals.getInstance().set_tunnelInstance(tun)
|
||||
mt_config.tunnelInstance = tun
|
||||
onTunnelReceive(packet, iface)
|
||||
assert re.search(r"in onTunnelReceive", caplog.text, re.MULTILINE)
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"""Meshtastic unit tests for util.py"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
from meshtastic.supported_device import SupportedDevice
|
||||
from meshtastic.protobuf import mesh_pb2
|
||||
from meshtastic.util import (
|
||||
Timeout,
|
||||
active_ports_on_supported_devices,
|
||||
@@ -30,6 +33,8 @@ from meshtastic.util import (
|
||||
snake_to_camel,
|
||||
stripnl,
|
||||
support_info,
|
||||
message_to_json,
|
||||
Acknowledgment
|
||||
)
|
||||
|
||||
|
||||
@@ -60,6 +65,7 @@ def test_fromStr():
|
||||
assert fromStr("123") == 123
|
||||
assert fromStr("abc") == "abc"
|
||||
assert fromStr("123456789") == 123456789
|
||||
assert fromStr("base64:Zm9vIGJhciBiYXo=") == b"foo bar baz"
|
||||
|
||||
|
||||
@pytest.mark.unitslow
|
||||
@@ -545,3 +551,46 @@ def test_active_ports_on_supported_devices_mac_duplicates_check(mock_platform, m
|
||||
}
|
||||
mock_platform.assert_called()
|
||||
mock_sp.assert_called()
|
||||
|
||||
@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(mesh_pb2.MyNodeInfo()))
|
||||
expected = { "myNodeNum": 0, "rebootCount": 0, "minAppVersion": 0 }
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_acknowledgement_reset():
|
||||
"""
|
||||
Test that the reset method can set all fields back to False
|
||||
"""
|
||||
test_ack_obj = Acknowledgment()
|
||||
# everything's set to False; let's set it to True to get a good test
|
||||
test_ack_obj.receivedAck = True
|
||||
test_ack_obj.receivedNak = True
|
||||
test_ack_obj.receivedImplAck = True
|
||||
test_ack_obj.receivedTraceRoute = True
|
||||
test_ack_obj.receivedTelemetry = True
|
||||
test_ack_obj.receivedPosition = True
|
||||
test_ack_obj.reset()
|
||||
assert test_ack_obj.receivedAck is False
|
||||
assert test_ack_obj.receivedNak is False
|
||||
assert test_ack_obj.receivedImplAck is False
|
||||
assert test_ack_obj.receivedTraceRoute is False
|
||||
assert test_ack_obj.receivedTelemetry is False
|
||||
assert test_ack_obj.receivedPosition is False
|
||||
|
||||
@given(a_string=st.text(
|
||||
alphabet=st.characters(
|
||||
codec='ascii',
|
||||
min_codepoint=0x5F,
|
||||
max_codepoint=0x7A,
|
||||
exclude_characters=r'`',
|
||||
)).filter(
|
||||
lambda x: x not in [''] and x[0] not in "_" and x[-1] not in '_' and not re.search(r'__', x)
|
||||
))
|
||||
def test_roundtrip_snake_to_camel_camel_to_snake(a_string):
|
||||
"""Test that snake_to_camel and camel_to_snake roundtrip each other"""
|
||||
value0 = snake_to_camel(a_string=a_string)
|
||||
value1 = camel_to_snake(a_string=value0)
|
||||
assert a_string == value1, (a_string, value1)
|
||||
|
||||
@@ -19,19 +19,18 @@ import logging
|
||||
import platform
|
||||
import threading
|
||||
|
||||
from pubsub import pub
|
||||
from pubsub import pub # type: ignore[import-untyped]
|
||||
from pytap2 import TapDevice
|
||||
|
||||
from meshtastic import portnums_pb2
|
||||
from meshtastic.globals import Globals
|
||||
from meshtastic.protobuf import portnums_pb2
|
||||
from meshtastic import mt_config
|
||||
from meshtastic.util import ipstr, readnet_u16
|
||||
|
||||
|
||||
def onTunnelReceive(packet, interface): # pylint: disable=W0613
|
||||
"""Callback for received tunneled messages from mesh."""
|
||||
logging.debug(f"in onTunnelReceive()")
|
||||
our_globals = Globals.getInstance()
|
||||
tunnelInstance = our_globals.get_tunnelInstance()
|
||||
tunnelInstance = mt_config.tunnelInstance
|
||||
tunnelInstance.onReceive(packet)
|
||||
|
||||
|
||||
@@ -67,8 +66,7 @@ class Tunnel:
|
||||
if platform.system() != "Linux":
|
||||
raise Tunnel.TunnelError("Tunnel() can only be run instantiated on a Linux system")
|
||||
|
||||
our_globals = Globals.getInstance()
|
||||
our_globals.set_tunnelInstance(self)
|
||||
mt_config.tunnelInstance = self
|
||||
|
||||
"""A list of chatty UDP services we should never accidentally
|
||||
forward to our slow network"""
|
||||
|
||||
@@ -11,6 +11,10 @@ import threading
|
||||
import time
|
||||
import traceback
|
||||
from queue import Queue
|
||||
from typing import List, NoReturn, Union
|
||||
|
||||
from google.protobuf.json_format import MessageToJson
|
||||
from google.protobuf.message import Message
|
||||
|
||||
import packaging.version as pkg_version
|
||||
import requests
|
||||
@@ -20,8 +24,15 @@ 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
|
||||
0x1915 NordicSemi (PPK2)
|
||||
"""
|
||||
blacklistVids = dict.fromkeys([0x1366, 0x0483, 0x1915])
|
||||
|
||||
"""Some devices are highly likely to be meshtastic.
|
||||
0x239a RAK4631
|
||||
0x303a Heltec tracker"""
|
||||
whitelistVids = dict.fromkeys([0x239a, 0x303a])
|
||||
|
||||
|
||||
def quoteBooleans(a_string):
|
||||
@@ -101,7 +112,7 @@ def pskToString(psk: bytes):
|
||||
return "secret"
|
||||
|
||||
|
||||
def stripnl(s):
|
||||
def stripnl(s) -> str:
|
||||
"""Remove newlines from a string (and remove extra whitespace)"""
|
||||
s = str(s).replace("\n", " ")
|
||||
return " ".join(s.split())
|
||||
@@ -120,26 +131,42 @@ def catchAndIgnore(reason, closure):
|
||||
logging.error(f"Exception thrown in {reason}: {ex}")
|
||||
|
||||
|
||||
def findPorts(eliminate_duplicates=False):
|
||||
def findPorts(eliminate_duplicates: bool=False) -> List[str]:
|
||||
"""Find all ports that might have meshtastic devices
|
||||
eliminate_duplicates will run the eliminate_duplicate_port() on the collection
|
||||
|
||||
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):
|
||||
@@ -153,16 +180,16 @@ class dotdict(dict):
|
||||
class Timeout:
|
||||
"""Timeout class"""
|
||||
|
||||
def __init__(self, maxSecs=20):
|
||||
self.expireTime = 0
|
||||
self.sleepInterval = 0.1
|
||||
self.expireTimeout = maxSecs
|
||||
def __init__(self, maxSecs: int=20):
|
||||
self.expireTime: Union[int, float] = 0
|
||||
self.sleepInterval: float = 0.1
|
||||
self.expireTimeout: int = maxSecs
|
||||
|
||||
def reset(self):
|
||||
"""Restart the waitForSet timer"""
|
||||
self.expireTime = time.time() + self.expireTimeout
|
||||
|
||||
def waitForSet(self, target, attrs=()):
|
||||
def waitForSet(self, target, attrs=()) -> bool:
|
||||
"""Block until the specified attributes are set. Returns True if config has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
@@ -173,7 +200,7 @@ class Timeout:
|
||||
|
||||
def waitForAckNak(
|
||||
self, acknowledgment, attrs=("receivedAck", "receivedNak", "receivedImplAck")
|
||||
):
|
||||
) -> bool:
|
||||
"""Block until an ACK or NAK has been received. Returns True if ACK or NAK has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
@@ -183,7 +210,7 @@ class Timeout:
|
||||
time.sleep(self.sleepInterval)
|
||||
return False
|
||||
|
||||
def waitForTraceRoute(self, waitFactor, acknowledgment, attr="receivedTraceRoute"):
|
||||
def waitForTraceRoute(self, waitFactor, acknowledgment, attr="receivedTraceRoute") -> bool:
|
||||
"""Block until traceroute response is received. Returns True if traceroute response has been received."""
|
||||
self.expireTimeout *= waitFactor
|
||||
self.reset()
|
||||
@@ -194,7 +221,7 @@ class Timeout:
|
||||
time.sleep(self.sleepInterval)
|
||||
return False
|
||||
|
||||
def waitForTelemetry(self, acknowledgment):
|
||||
def waitForTelemetry(self, acknowledgment) -> bool:
|
||||
"""Block until telemetry response is received. Returns True if telemetry response has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
@@ -204,6 +231,16 @@ class Timeout:
|
||||
time.sleep(self.sleepInterval)
|
||||
return False
|
||||
|
||||
def waitForPosition(self, acknowledgment) -> bool:
|
||||
"""Block until position response is received. Returns True if position response has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
if getattr(acknowledgment, "receivedPosition", None):
|
||||
acknowledgment.reset()
|
||||
return True
|
||||
time.sleep(self.sleepInterval)
|
||||
return False
|
||||
|
||||
class Acknowledgment:
|
||||
"A class that records which type of acknowledgment was just received, if any."
|
||||
|
||||
@@ -214,6 +251,7 @@ class Acknowledgment:
|
||||
self.receivedImplAck = False
|
||||
self.receivedTraceRoute = False
|
||||
self.receivedTelemetry = False
|
||||
self.receivedPosition = False
|
||||
|
||||
def reset(self):
|
||||
"""reset"""
|
||||
@@ -222,6 +260,7 @@ class Acknowledgment:
|
||||
self.receivedImplAck = False
|
||||
self.receivedTraceRoute = False
|
||||
self.receivedTelemetry = False
|
||||
self.receivedPosition = False
|
||||
|
||||
|
||||
class DeferredExecution:
|
||||
@@ -249,7 +288,7 @@ class DeferredExecution:
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
||||
def our_exit(message, return_value=1):
|
||||
def our_exit(message, return_value=1) -> NoReturn:
|
||||
"""Print the message and return a value.
|
||||
return_value defaults to 1 (non-successful)
|
||||
"""
|
||||
@@ -612,3 +651,9 @@ def check_if_newer_version():
|
||||
return None
|
||||
|
||||
return pypi_version
|
||||
|
||||
|
||||
def message_to_json(message: Message, multiline: bool=False) -> str:
|
||||
"""Return protobuf message as JSON. Always print all fields, even when not present in data."""
|
||||
json = MessageToJson(message, always_print_fields_with_no_presence=True)
|
||||
return stripnl(json) if not multiline else json
|
||||
|
||||
@@ -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\"\xab\x01\n\x06XModem\x12 \n\x07\x63ontrol\x18\x01 \x01(\x0e\x32\x0f.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x61\n\x13\x63om.geeksville.meshB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_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=28
|
||||
_XMODEM._serialized_end=199
|
||||
_XMODEM_CONTROL._serialized_start=116
|
||||
_XMODEM_CONTROL._serialized_end=199
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user