mirror of
https://github.com/meshtastic/python.git
synced 2026-01-05 14:27:54 -05:00
Remove old docs & add vercel badge to readme
This commit is contained in:
43
README.md
43
README.md
@@ -1,8 +1,8 @@
|
||||
# Meshtastic-python
|
||||
|
||||
[](https://open.vscode.dev/meshtastic/Meshtastic-python)
|
||||

|
||||
|
||||
|
||||
A python client for using [Meshtastic](https://www.meshtastic.org) devices. This small library (and example application) provides an easy API for sending and receiving messages over mesh radios. It also provides access to any of the operations/data available in the device user interface or the Android application. Events are delivered using a publish-subscribe model, and you can subscribe to only the message types you are interested in.
|
||||
|
||||
Full documentation including examples [here](https://meshtastic.github.io/Meshtastic-python/meshtastic/index.html).
|
||||
@@ -39,7 +39,7 @@ For the rough notes/implementation plan see [TODO](https://github.com/meshtastic
|
||||
|
||||
This pip package will also install a "meshtastic" command line executable, which displays packets sent over the network as JSON and lets you see serial debugging information from the meshtastic devices. The source code for this tool is also a good [example](https://github.com/meshtastic/Meshtastic-python/blob/master/meshtastic/__main__.py) of a 'complete' application that uses the meshtastic python API.
|
||||
|
||||
NOTE: This command is not run inside of python; you run it from your operating system shell prompt directly. If when you type "meshtastic" it doesn't find the command and you are using Windows: Check that the python "scripts" directory [is in your path](https://datatofish.com/add-python-to-windows-path/).
|
||||
NOTE: This command is not run inside of python; you run it from your operating system shell prompt directly. If when you type "meshtastic" it doesn't find the command and you are using Windows: Check that the python "scripts" directory [is in your path](https://datatofish.com/add-python-to-windows-path/).
|
||||
|
||||
To display a (partial) list of the available commands:
|
||||
|
||||
@@ -87,7 +87,7 @@ For a full list of preferences which can be set (and their documentation) see [h
|
||||
|
||||
### Changing channel settings
|
||||
|
||||
The channel settings can be changed similiarly. Either by using a standard (sharable) meshtastic URL or you can set partiular channel parameters (for advanced users).
|
||||
The channel settings can be changed similiarly. Either by using a standard (sharable) meshtastic URL or you can set partiular channel parameters (for advanced users).
|
||||
|
||||
The URL is constructed automatically based off of the current channel settings. So if you want to customize a channel you could do something like:
|
||||
|
||||
@@ -117,7 +117,7 @@ meshtastic --ch-index 1 --ch-set name mychan --ch-set channel_num 4 --info
|
||||
|
||||
## Ham radio support
|
||||
|
||||
Meshtastic is designed to be used without a radio operator license. If you do have a license you can set your operator ID and turn off encryption with:
|
||||
Meshtastic is designed to be used without a radio operator license. If you do have a license you can set your operator ID and turn off encryption with:
|
||||
|
||||
```
|
||||
meshtastic --port /dev/ttyUSB1 --set-ham KI1345
|
||||
@@ -131,6 +131,7 @@ Writing modified channels to device
|
||||
You can put parameters into a yaml file to update multiple values. See the [example_config.yaml](example_config.yaml).
|
||||
|
||||
This is how you might call it:
|
||||
|
||||
```
|
||||
meshtastic --configure example_config.yaml
|
||||
```
|
||||
@@ -141,13 +142,13 @@ This is a collection of common questions and answers from our friendly forum.
|
||||
|
||||
### [Permission denied: ‘/dev/ttyUSB0’](https://meshtastic.discourse.group/t/question-on-permission-denied-dev-ttyusb0/590/3?u=geeksville)
|
||||
|
||||
This indicates an OS permission problem for access by your user to the USB serial port. Typically this is fixed by the following.
|
||||
This indicates an OS permission problem for access by your user to the USB serial port. Typically this is fixed by the following.
|
||||
|
||||
```
|
||||
sudo usermod -a -G dialout $USER
|
||||
```
|
||||
|
||||
This adds the "dialout" group to your user. You'll need to obtain a new login session (for example, by logging out and logging back in) for the group change (and thus permission change) to take effect.
|
||||
This adds the "dialout" group to your user. You'll need to obtain a new login session (for example, by logging out and logging back in) for the group change (and thus permission change) to take effect.
|
||||
|
||||
## Mac OS Big Sur
|
||||
|
||||
@@ -161,7 +162,7 @@ Afterwards you can use the Meshtastic python client again on MacOS.
|
||||
|
||||
## A note to developers of this lib
|
||||
|
||||
We use the visual-studio-code default python formatting conventions (autopep8). So if you use that IDE you should be able to use "Format Document" and not generate unrelated diffs. If you use some other editor, please don't change formatting on lines you haven't changed.
|
||||
We use the visual-studio-code default python formatting conventions (autopep8). So if you use that IDE you should be able to use "Format Document" and not generate unrelated diffs. If you use some other editor, please don't change formatting on lines you haven't changed.
|
||||
|
||||
If you need to build a new release you'll need:
|
||||
|
||||
@@ -171,29 +172,33 @@ sudo pip3 install markdown pdoc3 webencodings pyparsing twine autopep8 pylint py
|
||||
```
|
||||
|
||||
For development, you will probably want to run:
|
||||
|
||||
```
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
|
||||
To lint, run:
|
||||
|
||||
```
|
||||
pylint meshtastic
|
||||
```
|
||||
|
||||
To test, first install this code locally, then run pytest:
|
||||
|
||||
```
|
||||
pip3 install .
|
||||
pytest
|
||||
```
|
||||
|
||||
Possible options for testing:
|
||||
* For more verbosity, add "-v" or even "-vv" like this:
|
||||
|
||||
- For more verbosity, add "-v" or even "-vv" like this:
|
||||
|
||||
```
|
||||
pytest -vv
|
||||
```
|
||||
|
||||
* To run just unit tests:
|
||||
- To run just unit tests:
|
||||
|
||||
```
|
||||
pytest
|
||||
@@ -203,13 +208,13 @@ pytest -m unit
|
||||
make
|
||||
```
|
||||
|
||||
* To run just integration tests:
|
||||
- To run just integration tests:
|
||||
|
||||
```
|
||||
pytest -m int
|
||||
```
|
||||
|
||||
* To run the smoke test with only one device connected serially (aka smoke1):
|
||||
- To run the smoke test with only one device connected serially (aka smoke1):
|
||||
|
||||
```
|
||||
pytest -m smoke1
|
||||
@@ -218,19 +223,19 @@ pytest -m smoke1
|
||||
CAUTION: Running smoke1 will reset values on the device, including the region to 1 (US).
|
||||
Be sure to hit the reset button on the device after the test is completed.
|
||||
|
||||
* To run the smoke test with only two device connected serially (aka smoke2):
|
||||
- To run the smoke test with only two device connected serially (aka smoke2):
|
||||
|
||||
```
|
||||
pytest -m smoke2
|
||||
```
|
||||
|
||||
* To run the wifi smoke test:
|
||||
- To run the wifi smoke test:
|
||||
|
||||
```
|
||||
pytest -m smokewifi
|
||||
```
|
||||
|
||||
* To run a specific test:
|
||||
- To run a specific test:
|
||||
|
||||
```
|
||||
pytest -msmoke1 meshtastic/tests/test_smoke1.py::test_smoke1_info
|
||||
@@ -240,9 +245,9 @@ pytest -m smoke2 meshtastic/tests/test_smoke2.py::test_smoke2_info
|
||||
pytest -m smokewifi meshtastic/tests/test_smoke_wifi.py::test_smokewifi_info
|
||||
```
|
||||
|
||||
* To add another classification of tests such as "unit" or "smoke1", see [pytest.ini](pytest.ini).
|
||||
- To add another classification of tests such as "unit" or "smoke1", see [pytest.ini](pytest.ini).
|
||||
|
||||
* To see the unit test code coverage:
|
||||
- To see the unit test code coverage:
|
||||
|
||||
```
|
||||
pytest --cov=meshtastic
|
||||
@@ -252,10 +257,12 @@ pytest --cov-report html --cov=meshtastic
|
||||
make cov
|
||||
```
|
||||
|
||||
* To see slowest unit tests, you can run:
|
||||
- To see slowest unit tests, you can run:
|
||||
|
||||
```
|
||||
pytest --durations=0
|
||||
# or
|
||||
make slow
|
||||
```
|
||||
|
||||
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; url=./meshtastic/index.html" />
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,332 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.admin_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.admin_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: admin.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from . import channel_pb2 as channel__pb2
|
||||
from . import mesh_pb2 as mesh__pb2
|
||||
from . import radioconfig_pb2 as radioconfig__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='admin.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\013AdminProtosH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x0b\x61\x64min.proto\x1a\rchannel.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\"\xfb\x02\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18! \x01(\x08H\x00\x12\x18\n\x0e\x65xit_simulator\x18\" \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18# \x01(\x05H\x00\x42\t\n\x07variantBG\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
,
|
||||
dependencies=[channel__pb2.DESCRIPTOR,mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,])
|
||||
|
||||
|
||||
|
||||
|
||||
_ADMINMESSAGE = _descriptor.Descriptor(
|
||||
name='AdminMessage',
|
||||
full_name='AdminMessage',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='set_radio', full_name='AdminMessage.set_radio', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='set_owner', full_name='AdminMessage.set_owner', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='set_channel', full_name='AdminMessage.set_channel', index=2,
|
||||
number=3, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='get_radio_request', full_name='AdminMessage.get_radio_request', index=3,
|
||||
number=4, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='get_radio_response', full_name='AdminMessage.get_radio_response', index=4,
|
||||
number=5, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='get_channel_request', full_name='AdminMessage.get_channel_request', index=5,
|
||||
number=6, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='get_channel_response', full_name='AdminMessage.get_channel_response', index=6,
|
||||
number=7, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='confirm_set_channel', full_name='AdminMessage.confirm_set_channel', index=7,
|
||||
number=32, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='confirm_set_radio', full_name='AdminMessage.confirm_set_radio', index=8,
|
||||
number=33, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='exit_simulator', full_name='AdminMessage.exit_simulator', index=9,
|
||||
number=34, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='reboot_seconds', full_name='AdminMessage.reboot_seconds', index=10,
|
||||
number=35, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
_descriptor.OneofDescriptor(
|
||||
name='variant', full_name='AdminMessage.variant',
|
||||
index=0, containing_type=None, fields=[]),
|
||||
],
|
||||
serialized_start=62,
|
||||
serialized_end=441,
|
||||
)
|
||||
|
||||
_ADMINMESSAGE.fields_by_name['set_radio'].message_type = radioconfig__pb2._RADIOCONFIG
|
||||
_ADMINMESSAGE.fields_by_name['set_owner'].message_type = mesh__pb2._USER
|
||||
_ADMINMESSAGE.fields_by_name['set_channel'].message_type = channel__pb2._CHANNEL
|
||||
_ADMINMESSAGE.fields_by_name['get_radio_response'].message_type = radioconfig__pb2._RADIOCONFIG
|
||||
_ADMINMESSAGE.fields_by_name['get_channel_response'].message_type = channel__pb2._CHANNEL
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['set_radio'])
|
||||
_ADMINMESSAGE.fields_by_name['set_radio'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['set_owner'])
|
||||
_ADMINMESSAGE.fields_by_name['set_owner'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['set_channel'])
|
||||
_ADMINMESSAGE.fields_by_name['set_channel'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['get_radio_request'])
|
||||
_ADMINMESSAGE.fields_by_name['get_radio_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['get_radio_response'])
|
||||
_ADMINMESSAGE.fields_by_name['get_radio_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['get_channel_request'])
|
||||
_ADMINMESSAGE.fields_by_name['get_channel_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['get_channel_response'])
|
||||
_ADMINMESSAGE.fields_by_name['get_channel_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['confirm_set_channel'])
|
||||
_ADMINMESSAGE.fields_by_name['confirm_set_channel'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['confirm_set_radio'])
|
||||
_ADMINMESSAGE.fields_by_name['confirm_set_radio'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['exit_simulator'])
|
||||
_ADMINMESSAGE.fields_by_name['exit_simulator'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
|
||||
_ADMINMESSAGE.fields_by_name['reboot_seconds'])
|
||||
_ADMINMESSAGE.fields_by_name['reboot_seconds'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
|
||||
DESCRIPTOR.message_types_by_name['AdminMessage'] = _ADMINMESSAGE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), {
|
||||
'DESCRIPTOR' : _ADMINMESSAGE,
|
||||
'__module__' : 'admin_pb2'
|
||||
# @@protoc_insertion_point(class_scope:AdminMessage)
|
||||
})
|
||||
_sym_db.RegisterMessage(AdminMessage)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage"><code class="flex name class">
|
||||
<span>class <span class="ident">AdminMessage</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.confirm_set_channel"><code class="name">var <span class="ident">confirm_set_channel</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.confirm_set_channel</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.confirm_set_radio"><code class="name">var <span class="ident">confirm_set_radio</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.confirm_set_radio</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.exit_simulator"><code class="name">var <span class="ident">exit_simulator</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.exit_simulator</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.get_channel_request"><code class="name">var <span class="ident">get_channel_request</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.get_channel_request</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.get_channel_response"><code class="name">var <span class="ident">get_channel_response</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.get_channel_response</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.get_radio_request"><code class="name">var <span class="ident">get_radio_request</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.get_radio_request</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.get_radio_response"><code class="name">var <span class="ident">get_radio_response</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.get_radio_response</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.reboot_seconds"><code class="name">var <span class="ident">reboot_seconds</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.reboot_seconds</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.set_channel"><code class="name">var <span class="ident">set_channel</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.set_channel</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.set_owner"><code class="name">var <span class="ident">set_owner</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.set_owner</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.admin_pb2.AdminMessage.set_radio"><code class="name">var <span class="ident">set_radio</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field AdminMessage.set_radio</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.admin_pb2.AdminMessage" href="#meshtastic.admin_pb2.AdminMessage">AdminMessage</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.DESCRIPTOR" href="#meshtastic.admin_pb2.AdminMessage.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.confirm_set_channel" href="#meshtastic.admin_pb2.AdminMessage.confirm_set_channel">confirm_set_channel</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.confirm_set_radio" href="#meshtastic.admin_pb2.AdminMessage.confirm_set_radio">confirm_set_radio</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.exit_simulator" href="#meshtastic.admin_pb2.AdminMessage.exit_simulator">exit_simulator</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.get_channel_request" href="#meshtastic.admin_pb2.AdminMessage.get_channel_request">get_channel_request</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.get_channel_response" href="#meshtastic.admin_pb2.AdminMessage.get_channel_response">get_channel_response</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.get_radio_request" href="#meshtastic.admin_pb2.AdminMessage.get_radio_request">get_radio_request</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.get_radio_response" href="#meshtastic.admin_pb2.AdminMessage.get_radio_response">get_radio_response</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.reboot_seconds" href="#meshtastic.admin_pb2.AdminMessage.reboot_seconds">reboot_seconds</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.set_channel" href="#meshtastic.admin_pb2.AdminMessage.set_channel">set_channel</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.set_owner" href="#meshtastic.admin_pb2.AdminMessage.set_owner">set_owner</a></code></li>
|
||||
<li><code><a title="meshtastic.admin_pb2.AdminMessage.set_radio" href="#meshtastic.admin_pb2.AdminMessage.set_radio">set_radio</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,170 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.apponly_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.apponly_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: apponly.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from . import channel_pb2 as channel__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='apponly.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\rapponly.proto\x1a\rchannel.proto\"0\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettingsBI\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
,
|
||||
dependencies=[channel__pb2.DESCRIPTOR,])
|
||||
|
||||
|
||||
|
||||
|
||||
_CHANNELSET = _descriptor.Descriptor(
|
||||
name='ChannelSet',
|
||||
full_name='ChannelSet',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='settings', full_name='ChannelSet.settings', index=0,
|
||||
number=1, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=32,
|
||||
serialized_end=80,
|
||||
)
|
||||
|
||||
_CHANNELSET.fields_by_name['settings'].message_type = channel__pb2._CHANNELSETTINGS
|
||||
DESCRIPTOR.message_types_by_name['ChannelSet'] = _CHANNELSET
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
ChannelSet = _reflection.GeneratedProtocolMessageType('ChannelSet', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CHANNELSET,
|
||||
'__module__' : 'apponly_pb2'
|
||||
# @@protoc_insertion_point(class_scope:ChannelSet)
|
||||
})
|
||||
_sym_db.RegisterMessage(ChannelSet)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.apponly_pb2.ChannelSet"><code class="flex name class">
|
||||
<span>class <span class="ident">ChannelSet</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.apponly_pb2.ChannelSet.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.apponly_pb2.ChannelSet.settings"><code class="name">var <span class="ident">settings</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSet.settings</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.apponly_pb2.ChannelSet" href="#meshtastic.apponly_pb2.ChannelSet">ChannelSet</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.apponly_pb2.ChannelSet.DESCRIPTOR" href="#meshtastic.apponly_pb2.ChannelSet.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.apponly_pb2.ChannelSet.settings" href="#meshtastic.apponly_pb2.ChannelSet.settings">settings</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,53 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.ble API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.ble</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,254 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.ble_interface API documentation</title>
|
||||
<meta name="description" content="Bluetooth interface" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.ble_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Bluetooth interface</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Bluetooth interface
|
||||
"""
|
||||
import logging
|
||||
import pygatt
|
||||
|
||||
|
||||
from .mesh_interface import MeshInterface
|
||||
|
||||
# Our standard BLE characteristics
|
||||
TORADIO_UUID = "f75c76d2-129e-4dad-a1dd-7866124401e7"
|
||||
FROMRADIO_UUID = "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
|
||||
FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453"
|
||||
|
||||
|
||||
class BLEInterface(MeshInterface):
|
||||
"""A not quite ready - FIXME - BLE interface to devices"""
|
||||
|
||||
def __init__(self, address, noProto=False, debugOut=None):
|
||||
self.address = address
|
||||
if not noProto:
|
||||
self.adapter = pygatt.GATTToolBackend() # BGAPIBackend()
|
||||
self.adapter.start()
|
||||
logging.debug(f"Connecting to {self.address}")
|
||||
self.device = self.adapter.connect(address)
|
||||
else:
|
||||
self.adapter = None
|
||||
self.device = None
|
||||
logging.debug("Connected to device")
|
||||
# fromradio = self.device.char_read(FROMRADIO_UUID)
|
||||
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
|
||||
|
||||
self._readFromRadio() # read the initial responses
|
||||
|
||||
def handle_data(handle, data):
|
||||
self._handleFromRadio(data)
|
||||
|
||||
if self.device:
|
||||
self.device.subscribe(FROMNUM_UUID, callback=handle_data)
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
#logging.debug(f"Sending: {stripnl(toRadio)}")
|
||||
b = toRadio.SerializeToString()
|
||||
self.device.char_write(TORADIO_UUID, b)
|
||||
|
||||
def close(self):
|
||||
MeshInterface.close(self)
|
||||
if self.adapter:
|
||||
self.adapter.stop()
|
||||
|
||||
def _readFromRadio(self):
|
||||
if not self.noProto:
|
||||
wasEmpty = False
|
||||
while not wasEmpty:
|
||||
if self.device:
|
||||
b = self.device.char_read(FROMRADIO_UUID)
|
||||
wasEmpty = len(b) == 0
|
||||
if not wasEmpty:
|
||||
self._handleFromRadio(b)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.ble_interface.BLEInterface"><code class="flex name class">
|
||||
<span>class <span class="ident">BLEInterface</span></span>
|
||||
<span>(</span><span>address, noProto=False, debugOut=None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A not quite ready - FIXME - BLE interface to devices</p>
|
||||
<p>Constructor</p>
|
||||
<p>Keyword Arguments:
|
||||
noProto – If True, don't try to run our protocol on the
|
||||
link - just be a dumb serial client.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class BLEInterface(MeshInterface):
|
||||
"""A not quite ready - FIXME - BLE interface to devices"""
|
||||
|
||||
def __init__(self, address, noProto=False, debugOut=None):
|
||||
self.address = address
|
||||
if not noProto:
|
||||
self.adapter = pygatt.GATTToolBackend() # BGAPIBackend()
|
||||
self.adapter.start()
|
||||
logging.debug(f"Connecting to {self.address}")
|
||||
self.device = self.adapter.connect(address)
|
||||
else:
|
||||
self.adapter = None
|
||||
self.device = None
|
||||
logging.debug("Connected to device")
|
||||
# fromradio = self.device.char_read(FROMRADIO_UUID)
|
||||
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
|
||||
|
||||
self._readFromRadio() # read the initial responses
|
||||
|
||||
def handle_data(handle, data):
|
||||
self._handleFromRadio(data)
|
||||
|
||||
if self.device:
|
||||
self.device.subscribe(FROMNUM_UUID, callback=handle_data)
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
#logging.debug(f"Sending: {stripnl(toRadio)}")
|
||||
b = toRadio.SerializeToString()
|
||||
self.device.char_write(TORADIO_UUID, b)
|
||||
|
||||
def close(self):
|
||||
MeshInterface.close(self)
|
||||
if self.adapter:
|
||||
self.adapter.stop()
|
||||
|
||||
def _readFromRadio(self):
|
||||
if not self.noProto:
|
||||
wasEmpty = False
|
||||
while not wasEmpty:
|
||||
if self.device:
|
||||
b = self.device.char_read(FROMRADIO_UUID)
|
||||
wasEmpty = len(b) == 0
|
||||
if not wasEmpty:
|
||||
self._handleFromRadio(b)</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></li>
|
||||
</ul>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.ble_interface.BLEInterface._readFromRadio"><code class="name flex">
|
||||
<span>def <span class="ident">_readFromRadio</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _readFromRadio(self):
|
||||
if not self.noProto:
|
||||
wasEmpty = False
|
||||
while not wasEmpty:
|
||||
if self.device:
|
||||
b = self.device.char_read(FROMRADIO_UUID)
|
||||
wasEmpty = len(b) == 0
|
||||
if not wasEmpty:
|
||||
self._handleFromRadio(b)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Inherited members</h3>
|
||||
<ul class="hlist">
|
||||
<li><code><b><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></b></code>:
|
||||
<ul class="hlist">
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._connected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._connected">_connected</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._disconnected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._disconnected">_disconnected</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._fixupPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._fixupPosition">_fixupPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._generatePacketId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._generatePacketId">_generatePacketId</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._getOrCreateByNum" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._getOrCreateByNum">_getOrCreateByNum</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handleConfigComplete" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleConfigComplete">_handleConfigComplete</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handleFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleFromRadio">_handleFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio">_handlePacketFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._nodeNumToId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._nodeNumToId">_nodeNumToId</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendDisconnect" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendDisconnect">_sendDisconnect</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendPacket" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendPacket">_sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendToRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadio">_sendToRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendToRadioImpl" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadioImpl">_sendToRadioImpl</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._startConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startConfig">_startConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._startHeartbeat" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startHeartbeat">_startHeartbeat</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._waitConnected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._waitConnected">_waitConnected</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.close" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.close">close</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getLongName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getLongName">getLongName</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getMyNodeInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyNodeInfo">getMyNodeInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getMyUser" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyUser">getMyUser</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getNode" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getNode">getNode</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getShortName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getShortName">getShortName</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendData" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendData">sendData</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendText" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.showInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showInfo">showInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.showNodes" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showNodes">showNodes</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.waitForConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.ble_interface.BLEInterface" href="#meshtastic.ble_interface.BLEInterface">BLEInterface</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.ble_interface.BLEInterface._readFromRadio" href="#meshtastic.ble_interface.BLEInterface._readFromRadio">_readFromRadio</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,509 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.channel_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.channel_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: channel.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='channel.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\rChannelProtosH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\rchannel.proto\"\x91\x03\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"\x8a\x01\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\x12\x13\n\x0f\x42w250Cr46Sf2048\x10\x04\x12\x13\n\x0f\x42w250Cr47Sf1024\x10\x05\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42I\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
)
|
||||
|
||||
|
||||
|
||||
_CHANNELSETTINGS_MODEMCONFIG = _descriptor.EnumDescriptor(
|
||||
name='ModemConfig',
|
||||
full_name='ChannelSettings.ModemConfig',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw125Cr45Sf128', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw500Cr45Sf128', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw31_25Cr48Sf512', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw125Cr48Sf4096', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw250Cr46Sf2048', index=4, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Bw250Cr47Sf1024', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=281,
|
||||
serialized_end=419,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_CHANNELSETTINGS_MODEMCONFIG)
|
||||
|
||||
_CHANNEL_ROLE = _descriptor.EnumDescriptor(
|
||||
name='Role',
|
||||
full_name='Channel.Role',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DISABLED', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='PRIMARY', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='SECONDARY', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=513,
|
||||
serialized_end=561,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_CHANNEL_ROLE)
|
||||
|
||||
|
||||
_CHANNELSETTINGS = _descriptor.Descriptor(
|
||||
name='ChannelSettings',
|
||||
full_name='ChannelSettings',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='tx_power', full_name='ChannelSettings.tx_power', index=0,
|
||||
number=1, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='modem_config', full_name='ChannelSettings.modem_config', index=1,
|
||||
number=3, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='bandwidth', full_name='ChannelSettings.bandwidth', index=2,
|
||||
number=6, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='spread_factor', full_name='ChannelSettings.spread_factor', index=3,
|
||||
number=7, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='coding_rate', full_name='ChannelSettings.coding_rate', index=4,
|
||||
number=8, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='channel_num', full_name='ChannelSettings.channel_num', index=5,
|
||||
number=9, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='psk', full_name='ChannelSettings.psk', index=6,
|
||||
number=4, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"",
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='name', full_name='ChannelSettings.name', index=7,
|
||||
number=5, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='id', full_name='ChannelSettings.id', index=8,
|
||||
number=10, type=7, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='uplink_enabled', full_name='ChannelSettings.uplink_enabled', index=9,
|
||||
number=16, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='downlink_enabled', full_name='ChannelSettings.downlink_enabled', index=10,
|
||||
number=17, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
_CHANNELSETTINGS_MODEMCONFIG,
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=18,
|
||||
serialized_end=419,
|
||||
)
|
||||
|
||||
|
||||
_CHANNEL = _descriptor.Descriptor(
|
||||
name='Channel',
|
||||
full_name='Channel',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='index', full_name='Channel.index', index=0,
|
||||
number=1, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='settings', full_name='Channel.settings', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='role', full_name='Channel.role', index=2,
|
||||
number=3, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
_CHANNEL_ROLE,
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=422,
|
||||
serialized_end=561,
|
||||
)
|
||||
|
||||
_CHANNELSETTINGS.fields_by_name['modem_config'].enum_type = _CHANNELSETTINGS_MODEMCONFIG
|
||||
_CHANNELSETTINGS_MODEMCONFIG.containing_type = _CHANNELSETTINGS
|
||||
_CHANNEL.fields_by_name['settings'].message_type = _CHANNELSETTINGS
|
||||
_CHANNEL.fields_by_name['role'].enum_type = _CHANNEL_ROLE
|
||||
_CHANNEL_ROLE.containing_type = _CHANNEL
|
||||
DESCRIPTOR.message_types_by_name['ChannelSettings'] = _CHANNELSETTINGS
|
||||
DESCRIPTOR.message_types_by_name['Channel'] = _CHANNEL
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CHANNELSETTINGS,
|
||||
'__module__' : 'channel_pb2'
|
||||
# @@protoc_insertion_point(class_scope:ChannelSettings)
|
||||
})
|
||||
_sym_db.RegisterMessage(ChannelSettings)
|
||||
|
||||
Channel = _reflection.GeneratedProtocolMessageType('Channel', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CHANNEL,
|
||||
'__module__' : 'channel_pb2'
|
||||
# @@protoc_insertion_point(class_scope:Channel)
|
||||
})
|
||||
_sym_db.RegisterMessage(Channel)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.channel_pb2.Channel"><code class="flex name class">
|
||||
<span>class <span class="ident">Channel</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.channel_pb2.Channel.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.DISABLED"><code class="name">var <span class="ident">DISABLED</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.PRIMARY"><code class="name">var <span class="ident">PRIMARY</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.Role"><code class="name">var <span class="ident">Role</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.SECONDARY"><code class="name">var <span class="ident">SECONDARY</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.channel_pb2.Channel.index"><code class="name">var <span class="ident">index</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field Channel.index</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.role"><code class="name">var <span class="ident">role</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field Channel.role</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.Channel.settings"><code class="name">var <span class="ident">settings</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field Channel.settings</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings"><code class="flex name class">
|
||||
<span>class <span class="ident">ChannelSettings</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw125Cr45Sf128"><code class="name">var <span class="ident">Bw125Cr45Sf128</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw125Cr48Sf4096"><code class="name">var <span class="ident">Bw125Cr48Sf4096</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw250Cr46Sf2048"><code class="name">var <span class="ident">Bw250Cr46Sf2048</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw250Cr47Sf1024"><code class="name">var <span class="ident">Bw250Cr47Sf1024</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw31_25Cr48Sf512"><code class="name">var <span class="ident">Bw31_25Cr48Sf512</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.Bw500Cr45Sf128"><code class="name">var <span class="ident">Bw500Cr45Sf128</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.ModemConfig"><code class="name">var <span class="ident">ModemConfig</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.bandwidth"><code class="name">var <span class="ident">bandwidth</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.bandwidth</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.channel_num"><code class="name">var <span class="ident">channel_num</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.channel_num</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.coding_rate"><code class="name">var <span class="ident">coding_rate</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.coding_rate</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.downlink_enabled"><code class="name">var <span class="ident">downlink_enabled</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.downlink_enabled</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.id"><code class="name">var <span class="ident">id</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.id</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.modem_config"><code class="name">var <span class="ident">modem_config</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.modem_config</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.name"><code class="name">var <span class="ident">name</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.name</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.psk"><code class="name">var <span class="ident">psk</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.psk</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.spread_factor"><code class="name">var <span class="ident">spread_factor</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.spread_factor</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.tx_power"><code class="name">var <span class="ident">tx_power</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.tx_power</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.channel_pb2.ChannelSettings.uplink_enabled"><code class="name">var <span class="ident">uplink_enabled</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelSettings.uplink_enabled</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.channel_pb2.Channel" href="#meshtastic.channel_pb2.Channel">Channel</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.DESCRIPTOR" href="#meshtastic.channel_pb2.Channel.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.DISABLED" href="#meshtastic.channel_pb2.Channel.DISABLED">DISABLED</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.PRIMARY" href="#meshtastic.channel_pb2.Channel.PRIMARY">PRIMARY</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.Role" href="#meshtastic.channel_pb2.Channel.Role">Role</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.SECONDARY" href="#meshtastic.channel_pb2.Channel.SECONDARY">SECONDARY</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.index" href="#meshtastic.channel_pb2.Channel.index">index</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.role" href="#meshtastic.channel_pb2.Channel.role">role</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.Channel.settings" href="#meshtastic.channel_pb2.Channel.settings">settings</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.channel_pb2.ChannelSettings" href="#meshtastic.channel_pb2.ChannelSettings">ChannelSettings</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw125Cr45Sf128" href="#meshtastic.channel_pb2.ChannelSettings.Bw125Cr45Sf128">Bw125Cr45Sf128</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw125Cr48Sf4096" href="#meshtastic.channel_pb2.ChannelSettings.Bw125Cr48Sf4096">Bw125Cr48Sf4096</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw250Cr46Sf2048" href="#meshtastic.channel_pb2.ChannelSettings.Bw250Cr46Sf2048">Bw250Cr46Sf2048</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw250Cr47Sf1024" href="#meshtastic.channel_pb2.ChannelSettings.Bw250Cr47Sf1024">Bw250Cr47Sf1024</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw31_25Cr48Sf512" href="#meshtastic.channel_pb2.ChannelSettings.Bw31_25Cr48Sf512">Bw31_25Cr48Sf512</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.Bw500Cr45Sf128" href="#meshtastic.channel_pb2.ChannelSettings.Bw500Cr45Sf128">Bw500Cr45Sf128</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.DESCRIPTOR" href="#meshtastic.channel_pb2.ChannelSettings.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.ModemConfig" href="#meshtastic.channel_pb2.ChannelSettings.ModemConfig">ModemConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.bandwidth" href="#meshtastic.channel_pb2.ChannelSettings.bandwidth">bandwidth</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.channel_num" href="#meshtastic.channel_pb2.ChannelSettings.channel_num">channel_num</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.coding_rate" href="#meshtastic.channel_pb2.ChannelSettings.coding_rate">coding_rate</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.downlink_enabled" href="#meshtastic.channel_pb2.ChannelSettings.downlink_enabled">downlink_enabled</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.id" href="#meshtastic.channel_pb2.ChannelSettings.id">id</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.modem_config" href="#meshtastic.channel_pb2.ChannelSettings.modem_config">modem_config</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.name" href="#meshtastic.channel_pb2.ChannelSettings.name">name</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.psk" href="#meshtastic.channel_pb2.ChannelSettings.psk">psk</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.spread_factor" href="#meshtastic.channel_pb2.ChannelSettings.spread_factor">spread_factor</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.tx_power" href="#meshtastic.channel_pb2.ChannelSettings.tx_power">tx_power</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2.ChannelSettings.uplink_enabled" href="#meshtastic.channel_pb2.ChannelSettings.uplink_enabled">uplink_enabled</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,464 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.deviceonly_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.deviceonly_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: deviceonly.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from . import channel_pb2 as channel__pb2
|
||||
from . import mesh_pb2 as mesh__pb2
|
||||
from . import radioconfig_pb2 as radioconfig__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='deviceonly.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\nDeviceOnlyH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x10\x64\x65viceonly.proto\x1a\rchannel.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\"\x80\x01\n\x11LegacyRadioConfig\x12\x39\n\x0bpreferences\x18\x01 \x01(\x0b\x32$.LegacyRadioConfig.LegacyPreferences\x1a\x30\n\x11LegacyPreferences\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\"\x8f\x02\n\x0b\x44\x65viceState\x12\'\n\x0blegacyRadio\x18\x01 \x01(\x0b\x32\x12.LegacyRadioConfig\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08J\x04\x08\x0c\x10\r\")\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.ChannelBF\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
,
|
||||
dependencies=[channel__pb2.DESCRIPTOR,mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,])
|
||||
|
||||
|
||||
|
||||
|
||||
_LEGACYRADIOCONFIG_LEGACYPREFERENCES = _descriptor.Descriptor(
|
||||
name='LegacyPreferences',
|
||||
full_name='LegacyRadioConfig.LegacyPreferences',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='region', full_name='LegacyRadioConfig.LegacyPreferences.region', index=0,
|
||||
number=15, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=147,
|
||||
serialized_end=195,
|
||||
)
|
||||
|
||||
_LEGACYRADIOCONFIG = _descriptor.Descriptor(
|
||||
name='LegacyRadioConfig',
|
||||
full_name='LegacyRadioConfig',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='preferences', full_name='LegacyRadioConfig.preferences', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[_LEGACYRADIOCONFIG_LEGACYPREFERENCES, ],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=67,
|
||||
serialized_end=195,
|
||||
)
|
||||
|
||||
|
||||
_DEVICESTATE = _descriptor.Descriptor(
|
||||
name='DeviceState',
|
||||
full_name='DeviceState',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='legacyRadio', full_name='DeviceState.legacyRadio', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='my_node', full_name='DeviceState.my_node', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='owner', full_name='DeviceState.owner', index=2,
|
||||
number=3, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='node_db', full_name='DeviceState.node_db', index=3,
|
||||
number=4, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='receive_queue', full_name='DeviceState.receive_queue', index=4,
|
||||
number=5, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='version', full_name='DeviceState.version', index=5,
|
||||
number=8, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='rx_text_message', full_name='DeviceState.rx_text_message', index=6,
|
||||
number=7, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='no_save', full_name='DeviceState.no_save', index=7,
|
||||
number=9, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='did_gps_reset', full_name='DeviceState.did_gps_reset', index=8,
|
||||
number=11, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=198,
|
||||
serialized_end=469,
|
||||
)
|
||||
|
||||
|
||||
_CHANNELFILE = _descriptor.Descriptor(
|
||||
name='ChannelFile',
|
||||
full_name='ChannelFile',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='channels', full_name='ChannelFile.channels', index=0,
|
||||
number=1, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=471,
|
||||
serialized_end=512,
|
||||
)
|
||||
|
||||
_LEGACYRADIOCONFIG_LEGACYPREFERENCES.fields_by_name['region'].enum_type = radioconfig__pb2._REGIONCODE
|
||||
_LEGACYRADIOCONFIG_LEGACYPREFERENCES.containing_type = _LEGACYRADIOCONFIG
|
||||
_LEGACYRADIOCONFIG.fields_by_name['preferences'].message_type = _LEGACYRADIOCONFIG_LEGACYPREFERENCES
|
||||
_DEVICESTATE.fields_by_name['legacyRadio'].message_type = _LEGACYRADIOCONFIG
|
||||
_DEVICESTATE.fields_by_name['my_node'].message_type = mesh__pb2._MYNODEINFO
|
||||
_DEVICESTATE.fields_by_name['owner'].message_type = mesh__pb2._USER
|
||||
_DEVICESTATE.fields_by_name['node_db'].message_type = mesh__pb2._NODEINFO
|
||||
_DEVICESTATE.fields_by_name['receive_queue'].message_type = mesh__pb2._MESHPACKET
|
||||
_DEVICESTATE.fields_by_name['rx_text_message'].message_type = mesh__pb2._MESHPACKET
|
||||
_CHANNELFILE.fields_by_name['channels'].message_type = channel__pb2._CHANNEL
|
||||
DESCRIPTOR.message_types_by_name['LegacyRadioConfig'] = _LEGACYRADIOCONFIG
|
||||
DESCRIPTOR.message_types_by_name['DeviceState'] = _DEVICESTATE
|
||||
DESCRIPTOR.message_types_by_name['ChannelFile'] = _CHANNELFILE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
LegacyRadioConfig = _reflection.GeneratedProtocolMessageType('LegacyRadioConfig', (_message.Message,), {
|
||||
|
||||
'LegacyPreferences' : _reflection.GeneratedProtocolMessageType('LegacyPreferences', (_message.Message,), {
|
||||
'DESCRIPTOR' : _LEGACYRADIOCONFIG_LEGACYPREFERENCES,
|
||||
'__module__' : 'deviceonly_pb2'
|
||||
# @@protoc_insertion_point(class_scope:LegacyRadioConfig.LegacyPreferences)
|
||||
})
|
||||
,
|
||||
'DESCRIPTOR' : _LEGACYRADIOCONFIG,
|
||||
'__module__' : 'deviceonly_pb2'
|
||||
# @@protoc_insertion_point(class_scope:LegacyRadioConfig)
|
||||
})
|
||||
_sym_db.RegisterMessage(LegacyRadioConfig)
|
||||
_sym_db.RegisterMessage(LegacyRadioConfig.LegacyPreferences)
|
||||
|
||||
DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.Message,), {
|
||||
'DESCRIPTOR' : _DEVICESTATE,
|
||||
'__module__' : 'deviceonly_pb2'
|
||||
# @@protoc_insertion_point(class_scope:DeviceState)
|
||||
})
|
||||
_sym_db.RegisterMessage(DeviceState)
|
||||
|
||||
ChannelFile = _reflection.GeneratedProtocolMessageType('ChannelFile', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CHANNELFILE,
|
||||
'__module__' : 'deviceonly_pb2'
|
||||
# @@protoc_insertion_point(class_scope:ChannelFile)
|
||||
})
|
||||
_sym_db.RegisterMessage(ChannelFile)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.ChannelFile"><code class="flex name class">
|
||||
<span>class <span class="ident">ChannelFile</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.ChannelFile.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.ChannelFile.channels"><code class="name">var <span class="ident">channels</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ChannelFile.channels</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState"><code class="flex name class">
|
||||
<span>class <span class="ident">DeviceState</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.did_gps_reset"><code class="name">var <span class="ident">did_gps_reset</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.did_gps_reset</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.legacyRadio"><code class="name">var <span class="ident">legacyRadio</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.legacyRadio</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.my_node"><code class="name">var <span class="ident">my_node</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.my_node</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.no_save"><code class="name">var <span class="ident">no_save</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.no_save</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.node_db"><code class="name">var <span class="ident">node_db</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.node_db</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.owner"><code class="name">var <span class="ident">owner</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.owner</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.receive_queue"><code class="name">var <span class="ident">receive_queue</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.receive_queue</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.rx_text_message"><code class="name">var <span class="ident">rx_text_message</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.rx_text_message</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.DeviceState.version"><code class="name">var <span class="ident">version</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field DeviceState.version</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.LegacyRadioConfig"><code class="flex name class">
|
||||
<span>class <span class="ident">LegacyRadioConfig</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.LegacyRadioConfig.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.deviceonly_pb2.LegacyRadioConfig.LegacyPreferences"><code class="name">var <span class="ident">LegacyPreferences</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.deviceonly_pb2.LegacyRadioConfig.preferences"><code class="name">var <span class="ident">preferences</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field LegacyRadioConfig.preferences</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.deviceonly_pb2.ChannelFile" href="#meshtastic.deviceonly_pb2.ChannelFile">ChannelFile</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.ChannelFile.DESCRIPTOR" href="#meshtastic.deviceonly_pb2.ChannelFile.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.ChannelFile.channels" href="#meshtastic.deviceonly_pb2.ChannelFile.channels">channels</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.deviceonly_pb2.DeviceState" href="#meshtastic.deviceonly_pb2.DeviceState">DeviceState</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.DESCRIPTOR" href="#meshtastic.deviceonly_pb2.DeviceState.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.did_gps_reset" href="#meshtastic.deviceonly_pb2.DeviceState.did_gps_reset">did_gps_reset</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.legacyRadio" href="#meshtastic.deviceonly_pb2.DeviceState.legacyRadio">legacyRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.my_node" href="#meshtastic.deviceonly_pb2.DeviceState.my_node">my_node</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.no_save" href="#meshtastic.deviceonly_pb2.DeviceState.no_save">no_save</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.node_db" href="#meshtastic.deviceonly_pb2.DeviceState.node_db">node_db</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.owner" href="#meshtastic.deviceonly_pb2.DeviceState.owner">owner</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.receive_queue" href="#meshtastic.deviceonly_pb2.DeviceState.receive_queue">receive_queue</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.rx_text_message" href="#meshtastic.deviceonly_pb2.DeviceState.rx_text_message">rx_text_message</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.DeviceState.version" href="#meshtastic.deviceonly_pb2.DeviceState.version">version</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.deviceonly_pb2.LegacyRadioConfig" href="#meshtastic.deviceonly_pb2.LegacyRadioConfig">LegacyRadioConfig</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.LegacyRadioConfig.DESCRIPTOR" href="#meshtastic.deviceonly_pb2.LegacyRadioConfig.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.LegacyRadioConfig.LegacyPreferences" href="#meshtastic.deviceonly_pb2.LegacyRadioConfig.LegacyPreferences">LegacyPreferences</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2.LegacyRadioConfig.preferences" href="#meshtastic.deviceonly_pb2.LegacyRadioConfig.preferences">preferences</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,191 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.environmental_measurement_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.environmental_measurement_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: environmental_measurement.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='environmental_measurement.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x1f\x65nvironmental_measurement.proto\"g\n\x18\x45nvironmentalMeasurement\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x42#Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
_ENVIRONMENTALMEASUREMENT = _descriptor.Descriptor(
|
||||
name='EnvironmentalMeasurement',
|
||||
full_name='EnvironmentalMeasurement',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='temperature', full_name='EnvironmentalMeasurement.temperature', index=0,
|
||||
number=1, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=float(0),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='relative_humidity', full_name='EnvironmentalMeasurement.relative_humidity', index=1,
|
||||
number=2, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=float(0),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='barometric_pressure', full_name='EnvironmentalMeasurement.barometric_pressure', index=2,
|
||||
number=3, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=float(0),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=35,
|
||||
serialized_end=138,
|
||||
)
|
||||
|
||||
DESCRIPTOR.message_types_by_name['EnvironmentalMeasurement'] = _ENVIRONMENTALMEASUREMENT
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
EnvironmentalMeasurement = _reflection.GeneratedProtocolMessageType('EnvironmentalMeasurement', (_message.Message,), {
|
||||
'DESCRIPTOR' : _ENVIRONMENTALMEASUREMENT,
|
||||
'__module__' : 'environmental_measurement_pb2'
|
||||
# @@protoc_insertion_point(class_scope:EnvironmentalMeasurement)
|
||||
})
|
||||
_sym_db.RegisterMessage(EnvironmentalMeasurement)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement"><code class="flex name class">
|
||||
<span>class <span class="ident">EnvironmentalMeasurement</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.barometric_pressure"><code class="name">var <span class="ident">barometric_pressure</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field EnvironmentalMeasurement.barometric_pressure</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.relative_humidity"><code class="name">var <span class="ident">relative_humidity</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field EnvironmentalMeasurement.relative_humidity</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.temperature"><code class="name">var <span class="ident">temperature</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field EnvironmentalMeasurement.temperature</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement" href="#meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement">EnvironmentalMeasurement</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.DESCRIPTOR" href="#meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.barometric_pressure" href="#meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.barometric_pressure">barometric_pressure</a></code></li>
|
||||
<li><code><a title="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.relative_humidity" href="#meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.relative_humidity">relative_humidity</a></code></li>
|
||||
<li><code><a title="meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.temperature" href="#meshtastic.environmental_measurement_pb2.EnvironmentalMeasurement.temperature">temperature</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,388 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.globals API documentation</title>
|
||||
<meta name="description" content="Globals singleton class …" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.globals</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Globals singleton class.</p>
|
||||
<p>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.</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""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")
|
||||
else:
|
||||
Globals.__instance = self
|
||||
self.args = None
|
||||
self.parser = None
|
||||
self.target_node = None
|
||||
self.channel_index = None
|
||||
|
||||
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.target_node = None
|
||||
self.channel_index = None
|
||||
|
||||
def set_args(self, args):
|
||||
"""Set the args"""
|
||||
self.args = args
|
||||
|
||||
def set_parser(self, parser):
|
||||
"""Set the parser"""
|
||||
self.parser = parser
|
||||
|
||||
def set_target_node(self, target_node):
|
||||
"""Set the target_node"""
|
||||
self.target_node = target_node
|
||||
|
||||
def set_channel_index(self, channel_index):
|
||||
"""Set the channel_index"""
|
||||
self.channel_index = channel_index
|
||||
|
||||
def get_args(self):
|
||||
"""Get args"""
|
||||
return self.args
|
||||
|
||||
def get_parser(self):
|
||||
"""Get parser"""
|
||||
return self.parser
|
||||
|
||||
def get_target_node(self):
|
||||
"""Get target_node"""
|
||||
return self.target_node
|
||||
|
||||
def get_channel_index(self):
|
||||
"""Get channel_index"""
|
||||
return self.channel_index</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.globals.Globals"><code class="flex name class">
|
||||
<span>class <span class="ident">Globals</span></span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Globals class is a Singleton.</p>
|
||||
<p>Constructor for the Globals CLass</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">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")
|
||||
else:
|
||||
Globals.__instance = self
|
||||
self.args = None
|
||||
self.parser = None
|
||||
self.target_node = None
|
||||
self.channel_index = None
|
||||
|
||||
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.target_node = None
|
||||
self.channel_index = None
|
||||
|
||||
def set_args(self, args):
|
||||
"""Set the args"""
|
||||
self.args = args
|
||||
|
||||
def set_parser(self, parser):
|
||||
"""Set the parser"""
|
||||
self.parser = parser
|
||||
|
||||
def set_target_node(self, target_node):
|
||||
"""Set the target_node"""
|
||||
self.target_node = target_node
|
||||
|
||||
def set_channel_index(self, channel_index):
|
||||
"""Set the channel_index"""
|
||||
self.channel_index = channel_index
|
||||
|
||||
def get_args(self):
|
||||
"""Get args"""
|
||||
return self.args
|
||||
|
||||
def get_parser(self):
|
||||
"""Get parser"""
|
||||
return self.parser
|
||||
|
||||
def get_target_node(self):
|
||||
"""Get target_node"""
|
||||
return self.target_node
|
||||
|
||||
def get_channel_index(self):
|
||||
"""Get channel_index"""
|
||||
return self.channel_index</code></pre>
|
||||
</details>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.globals.Globals._Globals__instance"><code class="name">var <span class="ident">_Globals__instance</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Static methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.globals.Globals.getInstance"><code class="name flex">
|
||||
<span>def <span class="ident">getInstance</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Get an instance of the Globals class.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@staticmethod
|
||||
def getInstance():
|
||||
"""Get an instance of the Globals class."""
|
||||
if Globals.__instance is None:
|
||||
Globals()
|
||||
return Globals.__instance</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.globals.Globals.get_args"><code class="name flex">
|
||||
<span>def <span class="ident">get_args</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Get args</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def get_args(self):
|
||||
"""Get args"""
|
||||
return self.args</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.get_channel_index"><code class="name flex">
|
||||
<span>def <span class="ident">get_channel_index</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Get channel_index</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def get_channel_index(self):
|
||||
"""Get channel_index"""
|
||||
return self.channel_index</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.get_parser"><code class="name flex">
|
||||
<span>def <span class="ident">get_parser</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Get parser</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def get_parser(self):
|
||||
"""Get parser"""
|
||||
return self.parser</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.get_target_node"><code class="name flex">
|
||||
<span>def <span class="ident">get_target_node</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Get target_node</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def get_target_node(self):
|
||||
"""Get target_node"""
|
||||
return self.target_node</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.reset"><code class="name flex">
|
||||
<span>def <span class="ident">reset</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Reset all of our globals. If you add a member, add it to this method, too.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">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.target_node = None
|
||||
self.channel_index = None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.set_args"><code class="name flex">
|
||||
<span>def <span class="ident">set_args</span></span>(<span>self, args)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set the args</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def set_args(self, args):
|
||||
"""Set the args"""
|
||||
self.args = args</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.set_channel_index"><code class="name flex">
|
||||
<span>def <span class="ident">set_channel_index</span></span>(<span>self, channel_index)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set the channel_index</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def set_channel_index(self, channel_index):
|
||||
"""Set the channel_index"""
|
||||
self.channel_index = channel_index</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.set_parser"><code class="name flex">
|
||||
<span>def <span class="ident">set_parser</span></span>(<span>self, parser)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set the parser</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def set_parser(self, parser):
|
||||
"""Set the parser"""
|
||||
self.parser = parser</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.globals.Globals.set_target_node"><code class="name flex">
|
||||
<span>def <span class="ident">set_target_node</span></span>(<span>self, target_node)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set the target_node</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def set_target_node(self, target_node):
|
||||
"""Set the target_node"""
|
||||
self.target_node = target_node</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.globals.Globals" href="#meshtastic.globals.Globals">Globals</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.globals.Globals._Globals__instance" href="#meshtastic.globals.Globals._Globals__instance">_Globals__instance</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.getInstance" href="#meshtastic.globals.Globals.getInstance">getInstance</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.get_args" href="#meshtastic.globals.Globals.get_args">get_args</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.get_channel_index" href="#meshtastic.globals.Globals.get_channel_index">get_channel_index</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.get_parser" href="#meshtastic.globals.Globals.get_parser">get_parser</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.get_target_node" href="#meshtastic.globals.Globals.get_target_node">get_target_node</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.reset" href="#meshtastic.globals.Globals.reset">reset</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.set_args" href="#meshtastic.globals.Globals.set_args">set_args</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.set_channel_index" href="#meshtastic.globals.Globals.set_channel_index">set_channel_index</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.set_parser" href="#meshtastic.globals.Globals.set_parser">set_parser</a></code></li>
|
||||
<li><code><a title="meshtastic.globals.Globals.set_target_node" href="#meshtastic.globals.Globals.set_target_node">set_target_node</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,767 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic API documentation</title>
|
||||
<meta name="description" content="an API for Meshtastic devices …" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Package <code>meshtastic</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<h1 id="an-api-for-meshtastic-devices">an API for Meshtastic devices</h1>
|
||||
<p>Primary class: SerialInterface
|
||||
Install with pip: "<a href="https://pypi.org/project/meshtastic/">pip3 install meshtastic</a>"
|
||||
Source code on <a href="https://github.com/meshtastic/Meshtastic-python">github</a></p>
|
||||
<p>properties of SerialInterface:</p>
|
||||
<ul>
|
||||
<li>radioConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
|
||||
the device.</li>
|
||||
<li>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.</li>
|
||||
<li>nodesByNum - like "nodes" but keyed by nodeNum instead of nodeId</li>
|
||||
<li>myInfo - Contains read-only information about the local radio device (software version, hardware version, etc)</li>
|
||||
</ul>
|
||||
<h1 id="published-pubsub-topics">Published PubSub topics</h1>
|
||||
<p>We use a <a href="https://pypubsub.readthedocs.io/en/v4.0.3/">publish-subscribe</a> model to communicate asynchronous events.
|
||||
Available
|
||||
topics:</p>
|
||||
<ul>
|
||||
<li>meshtastic.connection.established - published once we've successfully connected to the radio and downloaded the node DB</li>
|
||||
<li>meshtastic.connection.lost - published once we've lost our link to the radio</li>
|
||||
<li>meshtastic.receive.text(packet) - delivers a received packet as a dictionary, if you only care about a particular
|
||||
type of packet, you should subscribe to the full topic name.
|
||||
If you want to see all packets, simply subscribe to "meshtastic.receive".</li>
|
||||
<li>meshtastic.receive.position(packet)</li>
|
||||
<li>meshtastic.receive.user(packet)</li>
|
||||
<li>meshtastic.receive.data.portnum(packet) (where portnum is an integer or well known PortNum enum)</li>
|
||||
<li>meshtastic.node.updated(node = NodeInfo) - published when a node in the DB changes (appears, location changed, username changed, etc…)</li>
|
||||
</ul>
|
||||
<p>We receive position, user, or data packets from the mesh.
|
||||
You probably only care about meshtastic.receive.data.
|
||||
The first argument for
|
||||
that publish will be the packet.
|
||||
Text or binary data packets (from sendData or sendText) will both arrive this way.
|
||||
If you print packet
|
||||
you'll see the fields in the dictionary.
|
||||
decoded.data.payload will contain the raw bytes that were sent.
|
||||
If the packet was sent with
|
||||
sendText, decoded.data.text will <strong>also</strong> be populated with the decoded string.
|
||||
For ASCII these two strings will be the same, but for
|
||||
unicode scripts they can be different.</p>
|
||||
<h1 id="example-usage">Example Usage</h1>
|
||||
<pre><code>import meshtastic
|
||||
import meshtastic.serial_interface
|
||||
from pubsub import pub
|
||||
|
||||
def onReceive(packet, interface): # called when a packet arrives
|
||||
print(f"Received: {packet}")
|
||||
|
||||
def onConnection(interface, topic=pub.AUTO_TOPIC): # called when we (re)connect to the radio
|
||||
# defaults to broadcast, specify a destination ID if you wish
|
||||
interface.sendText("hello mesh")
|
||||
|
||||
pub.subscribe(onReceive, "meshtastic.receive")
|
||||
pub.subscribe(onConnection, "meshtastic.connection.established")
|
||||
# By default will try to find a meshtastic device, otherwise provide a device path like /dev/ttyUSB0
|
||||
interface = meshtastic.serial_interface.SerialInterface()
|
||||
|
||||
</code></pre>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""
|
||||
# an API for Meshtastic devices
|
||||
|
||||
Primary class: SerialInterface
|
||||
Install with pip: "[pip3 install meshtastic](https://pypi.org/project/meshtastic/)"
|
||||
Source code on [github](https://github.com/meshtastic/Meshtastic-python)
|
||||
|
||||
properties of SerialInterface:
|
||||
|
||||
- radioConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
|
||||
the device.
|
||||
- nodes - The database of received nodes. Includes always up-to-date location and username information for each
|
||||
node in the mesh. This is a read-only datastructure.
|
||||
- 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)
|
||||
|
||||
# Published PubSub topics
|
||||
|
||||
We use a [publish-subscribe](https://pypubsub.readthedocs.io/en/v4.0.3/) model to communicate asynchronous events. Available
|
||||
topics:
|
||||
|
||||
- meshtastic.connection.established - published once we've successfully connected to the radio and downloaded the node DB
|
||||
- meshtastic.connection.lost - published once we've lost our link to the radio
|
||||
- meshtastic.receive.text(packet) - delivers a received packet as a dictionary, if you only care about a particular
|
||||
type of packet, you should subscribe to the full topic name. If you want to see all packets, simply subscribe to "meshtastic.receive".
|
||||
- meshtastic.receive.position(packet)
|
||||
- meshtastic.receive.user(packet)
|
||||
- meshtastic.receive.data.portnum(packet) (where portnum is an integer or well known PortNum enum)
|
||||
- meshtastic.node.updated(node = NodeInfo) - published when a node in the DB changes (appears, location changed, username changed, etc...)
|
||||
|
||||
We receive position, user, or data packets from the mesh. You probably only care about meshtastic.receive.data. The first argument for
|
||||
that publish will be the packet. Text or binary data packets (from sendData or sendText) will both arrive this way. If you print packet
|
||||
you'll see the fields in the dictionary. decoded.data.payload will contain the raw bytes that were sent. If the packet was sent with
|
||||
sendText, decoded.data.text will **also** be populated with the decoded string. For ASCII these two strings will be the same, but for
|
||||
unicode scripts they can be different.
|
||||
|
||||
# Example Usage
|
||||
```
|
||||
import meshtastic
|
||||
import meshtastic.serial_interface
|
||||
from pubsub import pub
|
||||
|
||||
def onReceive(packet, interface): # called when a packet arrives
|
||||
print(f"Received: {packet}")
|
||||
|
||||
def onConnection(interface, topic=pub.AUTO_TOPIC): # called when we (re)connect to the radio
|
||||
# defaults to broadcast, specify a destination ID if you wish
|
||||
interface.sendText("hello mesh")
|
||||
|
||||
pub.subscribe(onReceive, "meshtastic.receive")
|
||||
pub.subscribe(onConnection, "meshtastic.connection.established")
|
||||
# By default will try to find a meshtastic device, otherwise provide a device path like /dev/ttyUSB0
|
||||
interface = meshtastic.serial_interface.SerialInterface()
|
||||
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
import base64
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import socket
|
||||
import sys
|
||||
import stat
|
||||
import threading
|
||||
import traceback
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import *
|
||||
import serial
|
||||
import timeago
|
||||
import google.protobuf.json_format
|
||||
import pygatt
|
||||
from pubsub import pub
|
||||
from dotmap import DotMap
|
||||
from tabulate import tabulate
|
||||
from google.protobuf.json_format import MessageToJson
|
||||
from .util import fixme, catchAndIgnore, stripnl, DeferredExecution, Timeout
|
||||
from .node import Node
|
||||
from . import mesh_pb2, portnums_pb2, apponly_pb2, admin_pb2, environmental_measurement_pb2, remote_hardware_pb2, channel_pb2, radioconfig_pb2, util
|
||||
|
||||
# Note: To follow PEP224, comments should be after the module variable.
|
||||
|
||||
LOCAL_ADDR = "^local"
|
||||
"""A special ID that means the local node"""
|
||||
|
||||
BROADCAST_NUM = 0xffffffff
|
||||
"""if using 8 bit nodenums this will be shortend on the target"""
|
||||
|
||||
BROADCAST_ADDR = "^all"
|
||||
"""A special ID that means broadcast"""
|
||||
|
||||
OUR_APP_VERSION = 20200
|
||||
"""The numeric buildnumber (shared with android apps) specifying the
|
||||
level of device code we are guaranteed to understand
|
||||
|
||||
format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
|
||||
"""
|
||||
|
||||
publishingThread = DeferredExecution("publishing")
|
||||
|
||||
|
||||
class ResponseHandler(NamedTuple):
|
||||
"""A pending response callback, waiting for a response to one of our messages"""
|
||||
# requestId: int - used only as a key
|
||||
callback: Callable
|
||||
# FIXME, add timestamp and age out old requests
|
||||
|
||||
|
||||
class KnownProtocol(NamedTuple):
|
||||
"""Used to automatically decode known protocol payloads"""
|
||||
name: str
|
||||
# portnum: int, now a key
|
||||
# If set, will be called to prase as a protocol buffer
|
||||
protobufFactory: Callable = None
|
||||
# If set, invoked as onReceive(interface, packet)
|
||||
onReceive: Callable = None
|
||||
|
||||
|
||||
def _onTextReceive(iface, asDict):
|
||||
"""Special text auto parsing for received messages"""
|
||||
# We don't throw if the utf8 is invalid in the text message. Instead we just don't populate
|
||||
# the decoded.data.text and we log an error message. This at least allows some delivery to
|
||||
# the app and the app can deal with the missing decoded representation.
|
||||
#
|
||||
# Usually btw this problem is caused by apps sending binary data but setting the payload type to
|
||||
# text.
|
||||
try:
|
||||
asBytes = asDict["decoded"]["payload"]
|
||||
asDict["decoded"]["text"] = asBytes.decode("utf-8")
|
||||
except Exception as ex:
|
||||
logging.error(f"Malformatted utf8 in text message: {ex}")
|
||||
_receiveInfoUpdate(iface, asDict)
|
||||
|
||||
|
||||
def _onPositionReceive(iface, asDict):
|
||||
"""Special auto parsing for received messages"""
|
||||
p = asDict["decoded"]["position"]
|
||||
iface._fixupPosition(p)
|
||||
# update node DB as needed
|
||||
iface._getOrCreateByNum(asDict["from"])["position"] = p
|
||||
|
||||
|
||||
def _onNodeInfoReceive(iface, asDict):
|
||||
"""Special auto parsing for received messages"""
|
||||
p = asDict["decoded"]["user"]
|
||||
# decode user protobufs and update nodedb, provide decoded version as "position" in the published msg
|
||||
# update node DB as needed
|
||||
n = iface._getOrCreateByNum(asDict["from"])
|
||||
n["user"] = p
|
||||
# We now have a node ID, make sure it is uptodate in that table
|
||||
iface.nodes[p["id"]] = n
|
||||
_receiveInfoUpdate(iface, asDict)
|
||||
|
||||
|
||||
def _receiveInfoUpdate(iface, asDict):
|
||||
if "from" in asDict:
|
||||
iface._getOrCreateByNum(asDict["from"])["lastReceived"] = asDict
|
||||
iface._getOrCreateByNum(asDict["from"])["lastHeard"] = asDict.get("rxTime")
|
||||
iface._getOrCreateByNum(asDict["from"])["snr"] = asDict.get("rxSnr")
|
||||
iface._getOrCreateByNum(asDict["from"])["hopLimit"] = asDict.get("hopLimit")
|
||||
|
||||
|
||||
"""Well known message payloads can register decoders for automatic protobuf parsing"""
|
||||
protocols = {
|
||||
portnums_pb2.PortNum.TEXT_MESSAGE_APP: KnownProtocol("text", onReceive=_onTextReceive),
|
||||
portnums_pb2.PortNum.POSITION_APP: KnownProtocol("position", mesh_pb2.Position, _onPositionReceive),
|
||||
portnums_pb2.PortNum.NODEINFO_APP: KnownProtocol("user", mesh_pb2.User, _onNodeInfoReceive),
|
||||
portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage),
|
||||
portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing),
|
||||
portnums_pb2.PortNum.ENVIRONMENTAL_MEASUREMENT_APP: KnownProtocol("environmental", environmental_measurement_pb2.EnvironmentalMeasurement),
|
||||
portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol(
|
||||
"remotehw", remote_hardware_pb2.HardwareMessage)
|
||||
}</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
||||
<dl>
|
||||
<dt><code class="name"><a title="meshtastic.admin_pb2" href="admin_pb2.html">meshtastic.admin_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.apponly_pb2" href="apponly_pb2.html">meshtastic.apponly_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.ble" href="ble.html">meshtastic.ble</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.ble_interface" href="ble_interface.html">meshtastic.ble_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Bluetooth interface</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.channel_pb2" href="channel_pb2.html">meshtastic.channel_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.deviceonly_pb2" href="deviceonly_pb2.html">meshtastic.deviceonly_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.environmental_measurement_pb2" href="environmental_measurement_pb2.html">meshtastic.environmental_measurement_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.globals" href="globals.html">meshtastic.globals</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Globals singleton class …</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.mesh_interface" href="mesh_interface.html">meshtastic.mesh_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Mesh Interface class</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.mesh_pb2" href="mesh_pb2.html">meshtastic.mesh_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.mqtt_pb2" href="mqtt_pb2.html">meshtastic.mqtt_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.node" href="node.html">meshtastic.node</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Node class</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.portnums_pb2" href="portnums_pb2.html">meshtastic.portnums_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.radioconfig_pb2" href="radioconfig_pb2.html">meshtastic.radioconfig_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.remote_hardware" href="remote_hardware.html">meshtastic.remote_hardware</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Remote hardware</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.remote_hardware_pb2" href="remote_hardware_pb2.html">meshtastic.remote_hardware_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.serial_interface" href="serial_interface.html">meshtastic.serial_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Serial interface class</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.storeforward_pb2" href="storeforward_pb2.html">meshtastic.storeforward_pb2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.stream_interface" href="stream_interface.html">meshtastic.stream_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Stream Interface base class</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tcp_interface" href="tcp_interface.html">meshtastic.tcp_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>TCPInterface class for interfacing with http endpoint</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.test" href="test.html">meshtastic.test</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>With two radios connected serially, send and receive test
|
||||
messages and report back if successful.</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests" href="tests/index.html">meshtastic.tests</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tunnel" href="tunnel.html">meshtastic.tunnel</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Code for IP tunnel over a mesh …</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.util" href="util.html">meshtastic.util</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Utility functions.</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-variables">Global variables</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.BROADCAST_ADDR"><code class="name">var <span class="ident">BROADCAST_ADDR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A special ID that means broadcast</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.BROADCAST_NUM"><code class="name">var <span class="ident">BROADCAST_NUM</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>if using 8 bit nodenums this will be shortend on the target</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.LOCAL_ADDR"><code class="name">var <span class="ident">LOCAL_ADDR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A special ID that means the local node</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.OUR_APP_VERSION"><code class="name">var <span class="ident">OUR_APP_VERSION</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>The numeric buildnumber (shared with android apps) specifying the
|
||||
level of device code we are guaranteed to understand</p>
|
||||
<p>format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic._onNodeInfoReceive"><code class="name flex">
|
||||
<span>def <span class="ident">_onNodeInfoReceive</span></span>(<span>iface, asDict)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Special auto parsing for received messages</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _onNodeInfoReceive(iface, asDict):
|
||||
"""Special auto parsing for received messages"""
|
||||
p = asDict["decoded"]["user"]
|
||||
# decode user protobufs and update nodedb, provide decoded version as "position" in the published msg
|
||||
# update node DB as needed
|
||||
n = iface._getOrCreateByNum(asDict["from"])
|
||||
n["user"] = p
|
||||
# We now have a node ID, make sure it is uptodate in that table
|
||||
iface.nodes[p["id"]] = n
|
||||
_receiveInfoUpdate(iface, asDict)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic._onPositionReceive"><code class="name flex">
|
||||
<span>def <span class="ident">_onPositionReceive</span></span>(<span>iface, asDict)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Special auto parsing for received messages</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _onPositionReceive(iface, asDict):
|
||||
"""Special auto parsing for received messages"""
|
||||
p = asDict["decoded"]["position"]
|
||||
iface._fixupPosition(p)
|
||||
# update node DB as needed
|
||||
iface._getOrCreateByNum(asDict["from"])["position"] = p</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic._onTextReceive"><code class="name flex">
|
||||
<span>def <span class="ident">_onTextReceive</span></span>(<span>iface, asDict)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Special text auto parsing for received messages</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _onTextReceive(iface, asDict):
|
||||
"""Special text auto parsing for received messages"""
|
||||
# We don't throw if the utf8 is invalid in the text message. Instead we just don't populate
|
||||
# the decoded.data.text and we log an error message. This at least allows some delivery to
|
||||
# the app and the app can deal with the missing decoded representation.
|
||||
#
|
||||
# Usually btw this problem is caused by apps sending binary data but setting the payload type to
|
||||
# text.
|
||||
try:
|
||||
asBytes = asDict["decoded"]["payload"]
|
||||
asDict["decoded"]["text"] = asBytes.decode("utf-8")
|
||||
except Exception as ex:
|
||||
logging.error(f"Malformatted utf8 in text message: {ex}")
|
||||
_receiveInfoUpdate(iface, asDict)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic._receiveInfoUpdate"><code class="name flex">
|
||||
<span>def <span class="ident">_receiveInfoUpdate</span></span>(<span>iface, asDict)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _receiveInfoUpdate(iface, asDict):
|
||||
if "from" in asDict:
|
||||
iface._getOrCreateByNum(asDict["from"])["lastReceived"] = asDict
|
||||
iface._getOrCreateByNum(asDict["from"])["lastHeard"] = asDict.get("rxTime")
|
||||
iface._getOrCreateByNum(asDict["from"])["snr"] = asDict.get("rxSnr")
|
||||
iface._getOrCreateByNum(asDict["from"])["hopLimit"] = asDict.get("hopLimit")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.KnownProtocol"><code class="flex name class">
|
||||
<span>class <span class="ident">KnownProtocol</span></span>
|
||||
<span>(</span><span>name: str, protobufFactory: Callable = None, onReceive: Callable = None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Used to automatically decode known protocol payloads</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class KnownProtocol(NamedTuple):
|
||||
"""Used to automatically decode known protocol payloads"""
|
||||
name: str
|
||||
# portnum: int, now a key
|
||||
# If set, will be called to prase as a protocol buffer
|
||||
protobufFactory: Callable = None
|
||||
# If set, invoked as onReceive(interface, packet)
|
||||
onReceive: Callable = None</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>builtins.tuple</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.KnownProtocol._field_defaults"><code class="name">var <span class="ident">_field_defaults</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.KnownProtocol._fields"><code class="name">var <span class="ident">_fields</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Static methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.KnownProtocol._make"><code class="name flex">
|
||||
<span>def <span class="ident">_make</span></span>(<span>iterable)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Make a new KnownProtocol object from a sequence or iterable</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@classmethod
|
||||
def _make(cls, iterable):
|
||||
result = tuple_new(cls, iterable)
|
||||
if _len(result) != num_fields:
|
||||
raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.KnownProtocol.name"><code class="name">var <span class="ident">name</span> : str</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Alias for field number 0</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.KnownProtocol.onReceive"><code class="name">var <span class="ident">onReceive</span> : Callable</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Alias for field number 2</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.KnownProtocol.protobufFactory"><code class="name">var <span class="ident">protobufFactory</span> : Callable</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Alias for field number 1</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.KnownProtocol._asdict"><code class="name flex">
|
||||
<span>def <span class="ident">_asdict</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Return a new dict which maps field names to their values.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _asdict(self):
|
||||
'Return a new dict which maps field names to their values.'
|
||||
return _dict(_zip(self._fields, self))</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.KnownProtocol._replace"><code class="name flex">
|
||||
<span>def <span class="ident">_replace</span></span>(<span>self, /, **kwds)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Return a new KnownProtocol object replacing specified fields with new values</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _replace(self, /, **kwds):
|
||||
result = self._make(_map(kwds.pop, field_names, self))
|
||||
if kwds:
|
||||
raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.ResponseHandler"><code class="flex name class">
|
||||
<span>class <span class="ident">ResponseHandler</span></span>
|
||||
<span>(</span><span>callback: Callable)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A pending response callback, waiting for a response to one of our messages</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class ResponseHandler(NamedTuple):
|
||||
"""A pending response callback, waiting for a response to one of our messages"""
|
||||
# requestId: int - used only as a key
|
||||
callback: Callable
|
||||
# FIXME, add timestamp and age out old requests</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>builtins.tuple</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.ResponseHandler._field_defaults"><code class="name">var <span class="ident">_field_defaults</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.ResponseHandler._fields"><code class="name">var <span class="ident">_fields</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Static methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.ResponseHandler._make"><code class="name flex">
|
||||
<span>def <span class="ident">_make</span></span>(<span>iterable)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Make a new ResponseHandler object from a sequence or iterable</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@classmethod
|
||||
def _make(cls, iterable):
|
||||
result = tuple_new(cls, iterable)
|
||||
if _len(result) != num_fields:
|
||||
raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.ResponseHandler.callback"><code class="name">var <span class="ident">callback</span> : Callable</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Alias for field number 0</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.ResponseHandler._asdict"><code class="name flex">
|
||||
<span>def <span class="ident">_asdict</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Return a new dict which maps field names to their values.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _asdict(self):
|
||||
'Return a new dict which maps field names to their values.'
|
||||
return _dict(_zip(self._fields, self))</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.ResponseHandler._replace"><code class="name flex">
|
||||
<span>def <span class="ident">_replace</span></span>(<span>self, /, **kwds)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Return a new ResponseHandler object replacing specified fields with new values</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _replace(self, /, **kwds):
|
||||
result = self._make(_map(kwds.pop, field_names, self))
|
||||
if kwds:
|
||||
raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul>
|
||||
<li><a href="#an-api-for-meshtastic-devices">an API for Meshtastic devices</a></li>
|
||||
<li><a href="#published-pubsub-topics">Published PubSub topics</a></li>
|
||||
<li><a href="#example-usage">Example Usage</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.admin_pb2" href="admin_pb2.html">meshtastic.admin_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.apponly_pb2" href="apponly_pb2.html">meshtastic.apponly_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.ble" href="ble.html">meshtastic.ble</a></code></li>
|
||||
<li><code><a title="meshtastic.ble_interface" href="ble_interface.html">meshtastic.ble_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.channel_pb2" href="channel_pb2.html">meshtastic.channel_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.deviceonly_pb2" href="deviceonly_pb2.html">meshtastic.deviceonly_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.environmental_measurement_pb2" href="environmental_measurement_pb2.html">meshtastic.environmental_measurement_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.globals" href="globals.html">meshtastic.globals</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface" href="mesh_interface.html">meshtastic.mesh_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_pb2" href="mesh_pb2.html">meshtastic.mesh_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.mqtt_pb2" href="mqtt_pb2.html">meshtastic.mqtt_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.node" href="node.html">meshtastic.node</a></code></li>
|
||||
<li><code><a title="meshtastic.portnums_pb2" href="portnums_pb2.html">meshtastic.portnums_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.radioconfig_pb2" href="radioconfig_pb2.html">meshtastic.radioconfig_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware" href="remote_hardware.html">meshtastic.remote_hardware</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2" href="remote_hardware_pb2.html">meshtastic.remote_hardware_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.serial_interface" href="serial_interface.html">meshtastic.serial_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2" href="storeforward_pb2.html">meshtastic.storeforward_pb2</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface" href="stream_interface.html">meshtastic.stream_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tcp_interface" href="tcp_interface.html">meshtastic.tcp_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.test" href="test.html">meshtastic.test</a></code></li>
|
||||
<li><code><a title="meshtastic.tests" href="tests/index.html">meshtastic.tests</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel" href="tunnel.html">meshtastic.tunnel</a></code></li>
|
||||
<li><code><a title="meshtastic.util" href="util.html">meshtastic.util</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-variables">Global variables</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.BROADCAST_ADDR" href="#meshtastic.BROADCAST_ADDR">BROADCAST_ADDR</a></code></li>
|
||||
<li><code><a title="meshtastic.BROADCAST_NUM" href="#meshtastic.BROADCAST_NUM">BROADCAST_NUM</a></code></li>
|
||||
<li><code><a title="meshtastic.LOCAL_ADDR" href="#meshtastic.LOCAL_ADDR">LOCAL_ADDR</a></code></li>
|
||||
<li><code><a title="meshtastic.OUR_APP_VERSION" href="#meshtastic.OUR_APP_VERSION">OUR_APP_VERSION</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic._onNodeInfoReceive" href="#meshtastic._onNodeInfoReceive">_onNodeInfoReceive</a></code></li>
|
||||
<li><code><a title="meshtastic._onPositionReceive" href="#meshtastic._onPositionReceive">_onPositionReceive</a></code></li>
|
||||
<li><code><a title="meshtastic._onTextReceive" href="#meshtastic._onTextReceive">_onTextReceive</a></code></li>
|
||||
<li><code><a title="meshtastic._receiveInfoUpdate" href="#meshtastic._receiveInfoUpdate">_receiveInfoUpdate</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.KnownProtocol" href="#meshtastic.KnownProtocol">KnownProtocol</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.KnownProtocol._asdict" href="#meshtastic.KnownProtocol._asdict">_asdict</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol._field_defaults" href="#meshtastic.KnownProtocol._field_defaults">_field_defaults</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol._fields" href="#meshtastic.KnownProtocol._fields">_fields</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol._make" href="#meshtastic.KnownProtocol._make">_make</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol._replace" href="#meshtastic.KnownProtocol._replace">_replace</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol.name" href="#meshtastic.KnownProtocol.name">name</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol.onReceive" href="#meshtastic.KnownProtocol.onReceive">onReceive</a></code></li>
|
||||
<li><code><a title="meshtastic.KnownProtocol.protobufFactory" href="#meshtastic.KnownProtocol.protobufFactory">protobufFactory</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.ResponseHandler" href="#meshtastic.ResponseHandler">ResponseHandler</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.ResponseHandler._asdict" href="#meshtastic.ResponseHandler._asdict">_asdict</a></code></li>
|
||||
<li><code><a title="meshtastic.ResponseHandler._field_defaults" href="#meshtastic.ResponseHandler._field_defaults">_field_defaults</a></code></li>
|
||||
<li><code><a title="meshtastic.ResponseHandler._fields" href="#meshtastic.ResponseHandler._fields">_fields</a></code></li>
|
||||
<li><code><a title="meshtastic.ResponseHandler._make" href="#meshtastic.ResponseHandler._make">_make</a></code></li>
|
||||
<li><code><a title="meshtastic.ResponseHandler._replace" href="#meshtastic.ResponseHandler._replace">_replace</a></code></li>
|
||||
<li><code><a title="meshtastic.ResponseHandler.callback" href="#meshtastic.ResponseHandler.callback">callback</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,194 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.mqtt_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.mqtt_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: mqtt.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from . import mesh_pb2 as mesh__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='mqtt.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\nMQTTProtosH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\nmqtt.proto\x1a\nmesh.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\tBF\n\x13\x63om.geeksville.meshB\nMQTTProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
,
|
||||
dependencies=[mesh__pb2.DESCRIPTOR,])
|
||||
|
||||
|
||||
|
||||
|
||||
_SERVICEENVELOPE = _descriptor.Descriptor(
|
||||
name='ServiceEnvelope',
|
||||
full_name='ServiceEnvelope',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='packet', full_name='ServiceEnvelope.packet', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='channel_id', full_name='ServiceEnvelope.channel_id', index=1,
|
||||
number=2, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='gateway_id', full_name='ServiceEnvelope.gateway_id', index=2,
|
||||
number=3, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=26,
|
||||
serialized_end=112,
|
||||
)
|
||||
|
||||
_SERVICEENVELOPE.fields_by_name['packet'].message_type = mesh__pb2._MESHPACKET
|
||||
DESCRIPTOR.message_types_by_name['ServiceEnvelope'] = _SERVICEENVELOPE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_message.Message,), {
|
||||
'DESCRIPTOR' : _SERVICEENVELOPE,
|
||||
'__module__' : 'mqtt_pb2'
|
||||
# @@protoc_insertion_point(class_scope:ServiceEnvelope)
|
||||
})
|
||||
_sym_db.RegisterMessage(ServiceEnvelope)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.mqtt_pb2.ServiceEnvelope"><code class="flex name class">
|
||||
<span>class <span class="ident">ServiceEnvelope</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.mqtt_pb2.ServiceEnvelope.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.mqtt_pb2.ServiceEnvelope.channel_id"><code class="name">var <span class="ident">channel_id</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ServiceEnvelope.channel_id</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.mqtt_pb2.ServiceEnvelope.gateway_id"><code class="name">var <span class="ident">gateway_id</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ServiceEnvelope.gateway_id</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.mqtt_pb2.ServiceEnvelope.packet"><code class="name">var <span class="ident">packet</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field ServiceEnvelope.packet</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.mqtt_pb2.ServiceEnvelope" href="#meshtastic.mqtt_pb2.ServiceEnvelope">ServiceEnvelope</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.mqtt_pb2.ServiceEnvelope.DESCRIPTOR" href="#meshtastic.mqtt_pb2.ServiceEnvelope.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.mqtt_pb2.ServiceEnvelope.channel_id" href="#meshtastic.mqtt_pb2.ServiceEnvelope.channel_id">channel_id</a></code></li>
|
||||
<li><code><a title="meshtastic.mqtt_pb2.ServiceEnvelope.gateway_id" href="#meshtastic.mqtt_pb2.ServiceEnvelope.gateway_id">gateway_id</a></code></li>
|
||||
<li><code><a title="meshtastic.mqtt_pb2.ServiceEnvelope.packet" href="#meshtastic.mqtt_pb2.ServiceEnvelope.packet">packet</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,190 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.portnums_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.portnums_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: portnums.proto
|
||||
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='portnums.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\010PortnumsH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x0eportnums.proto*\xcb\x02\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12!\n\x1d\x45NVIRONMENTAL_MEASUREMENT_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42\x44\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
)
|
||||
|
||||
_PORTNUM = _descriptor.EnumDescriptor(
|
||||
name='PortNum',
|
||||
full_name='PortNum',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='UNKNOWN_APP', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='TEXT_MESSAGE_APP', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='REMOTE_HARDWARE_APP', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='POSITION_APP', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='NODEINFO_APP', index=4, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTING_APP', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ADMIN_APP', index=6, number=6,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='REPLY_APP', index=7, number=32,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IP_TUNNEL_APP', index=8, number=33,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='SERIAL_APP', index=9, number=64,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='STORE_FORWARD_APP', index=10, number=65,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='RANGE_TEST_APP', index=11, number=66,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ENVIRONMENTAL_MEASUREMENT_APP', index=12, number=67,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ZPS_APP', index=13, number=68,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='PRIVATE_APP', index=14, number=256,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ATAK_FORWARDER', index=15, number=257,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='MAX', index=16, number=511,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=19,
|
||||
serialized_end=350,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_PORTNUM)
|
||||
|
||||
PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM)
|
||||
UNKNOWN_APP = 0
|
||||
TEXT_MESSAGE_APP = 1
|
||||
REMOTE_HARDWARE_APP = 2
|
||||
POSITION_APP = 3
|
||||
NODEINFO_APP = 4
|
||||
ROUTING_APP = 5
|
||||
ADMIN_APP = 6
|
||||
REPLY_APP = 32
|
||||
IP_TUNNEL_APP = 33
|
||||
SERIAL_APP = 64
|
||||
STORE_FORWARD_APP = 65
|
||||
RANGE_TEST_APP = 66
|
||||
ENVIRONMENTAL_MEASUREMENT_APP = 67
|
||||
ZPS_APP = 68
|
||||
PRIVATE_APP = 256
|
||||
ATAK_FORWARDER = 257
|
||||
MAX = 511
|
||||
|
||||
|
||||
DESCRIPTOR.enum_types_by_name['PortNum'] = _PORTNUM
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
@@ -1,342 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.remote_hardware API documentation</title>
|
||||
<meta name="description" content="Remote hardware" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.remote_hardware</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Remote hardware</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Remote hardware
|
||||
"""
|
||||
import logging
|
||||
from pubsub import pub
|
||||
from . import portnums_pb2, remote_hardware_pb2
|
||||
from .util import our_exit
|
||||
|
||||
|
||||
def onGPIOreceive(packet, interface):
|
||||
"""Callback for received GPIO responses
|
||||
"""
|
||||
logging.debug(f"packet:{packet} interface:{interface}")
|
||||
hw = packet["decoded"]["remotehw"]
|
||||
gpioValue = hw["gpioValue"]
|
||||
#print(f'mask:{interface.mask}')
|
||||
value = int(gpioValue) & int(interface.mask)
|
||||
print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={gpioValue} value={value}')
|
||||
interface.gotResponse = True
|
||||
|
||||
|
||||
class RemoteHardwareClient:
|
||||
"""
|
||||
This is the client code to control/monitor simple hardware built into the
|
||||
meshtastic devices. It is intended to be both a useful API/service and example
|
||||
code for how you can connect to your own custom meshtastic services
|
||||
"""
|
||||
|
||||
def __init__(self, iface):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
iface is the already open MeshInterface instance
|
||||
"""
|
||||
self.iface = iface
|
||||
ch = iface.localNode.getChannelByName("gpio")
|
||||
if not ch:
|
||||
our_exit(
|
||||
"Warning: No channel named 'gpio' was found.\n"\
|
||||
"On the sending and receive nodes create a channel named 'gpio'.\n"\
|
||||
"For example, run '--ch-add gpio' on one device, then '--seturl' on\n"\
|
||||
"the other devices using the url from the device where the channel was added.")
|
||||
self.channelIndex = ch.index
|
||||
|
||||
pub.subscribe(onGPIOreceive, "meshtastic.receive.remotehw")
|
||||
|
||||
def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None):
|
||||
if not nodeid:
|
||||
our_exit(r"Warning: Must use a destination node ID for this operation (use --dest \!xxxxxxxxx)")
|
||||
return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP,
|
||||
wantAck=True, channelIndex=self.channelIndex,
|
||||
wantResponse=wantResponse, onResponse=onResponse)
|
||||
|
||||
def writeGPIOs(self, nodeid, mask, vals):
|
||||
"""
|
||||
Write the specified vals bits to the device GPIOs. Only bits in mask that
|
||||
are 1 will be changed
|
||||
"""
|
||||
logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
|
||||
r.gpio_mask = mask
|
||||
r.gpio_value = vals
|
||||
return self._sendHardware(nodeid, r)
|
||||
|
||||
def readGPIOs(self, nodeid, mask, onResponse = None):
|
||||
"""Read the specified bits from GPIO inputs on the device"""
|
||||
logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
|
||||
r.gpio_mask = mask
|
||||
return self._sendHardware(nodeid, r, wantResponse=True, onResponse=onResponse)
|
||||
|
||||
def watchGPIOs(self, nodeid, mask):
|
||||
"""Watch the specified bits from GPIO inputs on the device for changes"""
|
||||
logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
|
||||
r.gpio_mask = mask
|
||||
self.iface.mask = mask
|
||||
return self._sendHardware(nodeid, r)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware.onGPIOreceive"><code class="name flex">
|
||||
<span>def <span class="ident">onGPIOreceive</span></span>(<span>packet, interface)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Callback for received GPIO responses</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onGPIOreceive(packet, interface):
|
||||
"""Callback for received GPIO responses
|
||||
"""
|
||||
logging.debug(f"packet:{packet} interface:{interface}")
|
||||
hw = packet["decoded"]["remotehw"]
|
||||
gpioValue = hw["gpioValue"]
|
||||
#print(f'mask:{interface.mask}')
|
||||
value = int(gpioValue) & int(interface.mask)
|
||||
print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={gpioValue} value={value}')
|
||||
interface.gotResponse = True</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware.RemoteHardwareClient"><code class="flex name class">
|
||||
<span>class <span class="ident">RemoteHardwareClient</span></span>
|
||||
<span>(</span><span>iface)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>This is the client code to control/monitor simple hardware built into the
|
||||
meshtastic devices.
|
||||
It is intended to be both a useful API/service and example
|
||||
code for how you can connect to your own custom meshtastic services</p>
|
||||
<p>Constructor</p>
|
||||
<p>iface is the already open MeshInterface instance</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class RemoteHardwareClient:
|
||||
"""
|
||||
This is the client code to control/monitor simple hardware built into the
|
||||
meshtastic devices. It is intended to be both a useful API/service and example
|
||||
code for how you can connect to your own custom meshtastic services
|
||||
"""
|
||||
|
||||
def __init__(self, iface):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
iface is the already open MeshInterface instance
|
||||
"""
|
||||
self.iface = iface
|
||||
ch = iface.localNode.getChannelByName("gpio")
|
||||
if not ch:
|
||||
our_exit(
|
||||
"Warning: No channel named 'gpio' was found.\n"\
|
||||
"On the sending and receive nodes create a channel named 'gpio'.\n"\
|
||||
"For example, run '--ch-add gpio' on one device, then '--seturl' on\n"\
|
||||
"the other devices using the url from the device where the channel was added.")
|
||||
self.channelIndex = ch.index
|
||||
|
||||
pub.subscribe(onGPIOreceive, "meshtastic.receive.remotehw")
|
||||
|
||||
def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None):
|
||||
if not nodeid:
|
||||
our_exit(r"Warning: Must use a destination node ID for this operation (use --dest \!xxxxxxxxx)")
|
||||
return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP,
|
||||
wantAck=True, channelIndex=self.channelIndex,
|
||||
wantResponse=wantResponse, onResponse=onResponse)
|
||||
|
||||
def writeGPIOs(self, nodeid, mask, vals):
|
||||
"""
|
||||
Write the specified vals bits to the device GPIOs. Only bits in mask that
|
||||
are 1 will be changed
|
||||
"""
|
||||
logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
|
||||
r.gpio_mask = mask
|
||||
r.gpio_value = vals
|
||||
return self._sendHardware(nodeid, r)
|
||||
|
||||
def readGPIOs(self, nodeid, mask, onResponse = None):
|
||||
"""Read the specified bits from GPIO inputs on the device"""
|
||||
logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
|
||||
r.gpio_mask = mask
|
||||
return self._sendHardware(nodeid, r, wantResponse=True, onResponse=onResponse)
|
||||
|
||||
def watchGPIOs(self, nodeid, mask):
|
||||
"""Watch the specified bits from GPIO inputs on the device for changes"""
|
||||
logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
|
||||
r.gpio_mask = mask
|
||||
self.iface.mask = mask
|
||||
return self._sendHardware(nodeid, r)</code></pre>
|
||||
</details>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware.RemoteHardwareClient._sendHardware"><code class="name flex">
|
||||
<span>def <span class="ident">_sendHardware</span></span>(<span>self, nodeid, r, wantResponse=False, onResponse=None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None):
|
||||
if not nodeid:
|
||||
our_exit(r"Warning: Must use a destination node ID for this operation (use --dest \!xxxxxxxxx)")
|
||||
return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP,
|
||||
wantAck=True, channelIndex=self.channelIndex,
|
||||
wantResponse=wantResponse, onResponse=onResponse)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware.RemoteHardwareClient.readGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">readGPIOs</span></span>(<span>self, nodeid, mask, onResponse=None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Read the specified bits from GPIO inputs on the device</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def readGPIOs(self, nodeid, mask, onResponse = None):
|
||||
"""Read the specified bits from GPIO inputs on the device"""
|
||||
logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
|
||||
r.gpio_mask = mask
|
||||
return self._sendHardware(nodeid, r, wantResponse=True, onResponse=onResponse)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware.RemoteHardwareClient.watchGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">watchGPIOs</span></span>(<span>self, nodeid, mask)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Watch the specified bits from GPIO inputs on the device for changes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def watchGPIOs(self, nodeid, mask):
|
||||
"""Watch the specified bits from GPIO inputs on the device for changes"""
|
||||
logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
|
||||
r.gpio_mask = mask
|
||||
self.iface.mask = mask
|
||||
return self._sendHardware(nodeid, r)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware.RemoteHardwareClient.writeGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">writeGPIOs</span></span>(<span>self, nodeid, mask, vals)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Write the specified vals bits to the device GPIOs.
|
||||
Only bits in mask that
|
||||
are 1 will be changed</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def writeGPIOs(self, nodeid, mask, vals):
|
||||
"""
|
||||
Write the specified vals bits to the device GPIOs. Only bits in mask that
|
||||
are 1 will be changed
|
||||
"""
|
||||
logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
|
||||
r = remote_hardware_pb2.HardwareMessage()
|
||||
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
|
||||
r.gpio_mask = mask
|
||||
r.gpio_value = vals
|
||||
return self._sendHardware(nodeid, r)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.remote_hardware.onGPIOreceive" href="#meshtastic.remote_hardware.onGPIOreceive">onGPIOreceive</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.remote_hardware.RemoteHardwareClient" href="#meshtastic.remote_hardware.RemoteHardwareClient">RemoteHardwareClient</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.remote_hardware.RemoteHardwareClient._sendHardware" href="#meshtastic.remote_hardware.RemoteHardwareClient._sendHardware">_sendHardware</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware.RemoteHardwareClient.readGPIOs" href="#meshtastic.remote_hardware.RemoteHardwareClient.readGPIOs">readGPIOs</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware.RemoteHardwareClient.watchGPIOs" href="#meshtastic.remote_hardware.RemoteHardwareClient.watchGPIOs">watchGPIOs</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware.RemoteHardwareClient.writeGPIOs" href="#meshtastic.remote_hardware.RemoteHardwareClient.writeGPIOs">writeGPIOs</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,267 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.remote_hardware_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.remote_hardware_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: remote_hardware.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='remote_hardware.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\016RemoteHardwareH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x15remote_hardware.proto\"\xca\x01\n\x0fHardwareMessage\x12\"\n\x03typ\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\x42J\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
)
|
||||
|
||||
|
||||
|
||||
_HARDWAREMESSAGE_TYPE = _descriptor.EnumDescriptor(
|
||||
name='Type',
|
||||
full_name='HardwareMessage.Type',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='UNSET', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='WRITE_GPIOS', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='WATCH_GPIOS', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='GPIOS_CHANGED', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='READ_GPIOS', index=4, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='READ_GPIOS_REPLY', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=120,
|
||||
serialized_end=228,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_HARDWAREMESSAGE_TYPE)
|
||||
|
||||
|
||||
_HARDWAREMESSAGE = _descriptor.Descriptor(
|
||||
name='HardwareMessage',
|
||||
full_name='HardwareMessage',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='typ', full_name='HardwareMessage.typ', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='gpio_mask', full_name='HardwareMessage.gpio_mask', index=1,
|
||||
number=2, type=4, cpp_type=4, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='gpio_value', full_name='HardwareMessage.gpio_value', index=2,
|
||||
number=3, type=4, cpp_type=4, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
_HARDWAREMESSAGE_TYPE,
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=26,
|
||||
serialized_end=228,
|
||||
)
|
||||
|
||||
_HARDWAREMESSAGE.fields_by_name['typ'].enum_type = _HARDWAREMESSAGE_TYPE
|
||||
_HARDWAREMESSAGE_TYPE.containing_type = _HARDWAREMESSAGE
|
||||
DESCRIPTOR.message_types_by_name['HardwareMessage'] = _HARDWAREMESSAGE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
HardwareMessage = _reflection.GeneratedProtocolMessageType('HardwareMessage', (_message.Message,), {
|
||||
'DESCRIPTOR' : _HARDWAREMESSAGE,
|
||||
'__module__' : 'remote_hardware_pb2'
|
||||
# @@protoc_insertion_point(class_scope:HardwareMessage)
|
||||
})
|
||||
_sym_db.RegisterMessage(HardwareMessage)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage"><code class="flex name class">
|
||||
<span>class <span class="ident">HardwareMessage</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.GPIOS_CHANGED"><code class="name">var <span class="ident">GPIOS_CHANGED</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS"><code class="name">var <span class="ident">READ_GPIOS</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS_REPLY"><code class="name">var <span class="ident">READ_GPIOS_REPLY</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.Type"><code class="name">var <span class="ident">Type</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.UNSET"><code class="name">var <span class="ident">UNSET</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.WATCH_GPIOS"><code class="name">var <span class="ident">WATCH_GPIOS</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.WRITE_GPIOS"><code class="name">var <span class="ident">WRITE_GPIOS</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.gpio_mask"><code class="name">var <span class="ident">gpio_mask</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field HardwareMessage.gpio_mask</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.gpio_value"><code class="name">var <span class="ident">gpio_value</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field HardwareMessage.gpio_value</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.remote_hardware_pb2.HardwareMessage.typ"><code class="name">var <span class="ident">typ</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field HardwareMessage.typ</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage" href="#meshtastic.remote_hardware_pb2.HardwareMessage">HardwareMessage</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.DESCRIPTOR" href="#meshtastic.remote_hardware_pb2.HardwareMessage.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.GPIOS_CHANGED" href="#meshtastic.remote_hardware_pb2.HardwareMessage.GPIOS_CHANGED">GPIOS_CHANGED</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS" href="#meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS">READ_GPIOS</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS_REPLY" href="#meshtastic.remote_hardware_pb2.HardwareMessage.READ_GPIOS_REPLY">READ_GPIOS_REPLY</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.Type" href="#meshtastic.remote_hardware_pb2.HardwareMessage.Type">Type</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.UNSET" href="#meshtastic.remote_hardware_pb2.HardwareMessage.UNSET">UNSET</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.WATCH_GPIOS" href="#meshtastic.remote_hardware_pb2.HardwareMessage.WATCH_GPIOS">WATCH_GPIOS</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.WRITE_GPIOS" href="#meshtastic.remote_hardware_pb2.HardwareMessage.WRITE_GPIOS">WRITE_GPIOS</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.gpio_mask" href="#meshtastic.remote_hardware_pb2.HardwareMessage.gpio_mask">gpio_mask</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.gpio_value" href="#meshtastic.remote_hardware_pb2.HardwareMessage.gpio_value">gpio_value</a></code></li>
|
||||
<li><code><a title="meshtastic.remote_hardware_pb2.HardwareMessage.typ" href="#meshtastic.remote_hardware_pb2.HardwareMessage.typ">typ</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,323 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.serial_interface API documentation</title>
|
||||
<meta name="description" content="Serial interface class" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.serial_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Serial interface class</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">""" Serial interface class
|
||||
"""
|
||||
import logging
|
||||
import platform
|
||||
import os
|
||||
import stat
|
||||
import serial
|
||||
|
||||
import meshtastic.util
|
||||
from .stream_interface import StreamInterface
|
||||
|
||||
class SerialInterface(StreamInterface):
|
||||
"""Interface class for meshtastic devices over a serial link"""
|
||||
|
||||
def __init__(self, devPath=None, debugOut=None, noProto=False, connectNow=True):
|
||||
"""Constructor, opens a connection to a specified serial port, or if unspecified try to
|
||||
find one Meshtastic device by probing
|
||||
|
||||
Keyword Arguments:
|
||||
devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
|
||||
debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None})
|
||||
"""
|
||||
|
||||
if devPath is None:
|
||||
ports = meshtastic.util.findPorts()
|
||||
logging.debug(f"ports:{ports}")
|
||||
if len(ports) == 0:
|
||||
meshtastic.util.our_exit("Warning: No Meshtastic devices detected.")
|
||||
elif len(ports) > 1:
|
||||
message = "Warning: Multiple serial ports were detected so one serial port must be specified with the '--port'.\n"
|
||||
message += f" Ports detected:{ports}"
|
||||
meshtastic.util.our_exit(message)
|
||||
else:
|
||||
devPath = ports[0]
|
||||
|
||||
logging.debug(f"Connecting to {devPath}")
|
||||
|
||||
# Note: we provide None for port here, because we will be opening it later
|
||||
self.stream = serial.Serial(
|
||||
None, 921600, exclusive=True, timeout=0.5, write_timeout=0)
|
||||
|
||||
# rts=False Needed to prevent TBEAMs resetting on OSX, because rts is connected to reset
|
||||
self.stream.port = devPath
|
||||
|
||||
# HACK: If the platform driving the serial port is unable to leave the RTS pin in high-impedance
|
||||
# mode, set RTS to false so that the device platform won't be reset spuriously.
|
||||
# Linux does this properly, so don't apply this hack on Linux (because it makes the reset button not work).
|
||||
if self._hostPlatformAlwaysDrivesUartRts():
|
||||
self.stream.rts = False
|
||||
self.stream.open()
|
||||
|
||||
StreamInterface.__init__(
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow)
|
||||
|
||||
"""true if platform driving the serial port is Windows Subsystem for Linux 1."""
|
||||
def _isWsl1(self):
|
||||
# WSL1 identifies itself as Linux, but has a special char device at /dev/lxss for use with session control,
|
||||
# e.g. /init. We should treat WSL1 as Windows for the RTS-driving hack because the underlying platfrom
|
||||
# serial driver for the CP21xx still exhibits the buggy behavior.
|
||||
# WSL2 is not covered here, as it does not (as of 2021-May-25) support the appropriate functionality to
|
||||
# share or pass-through serial ports.
|
||||
try:
|
||||
# Claims to be Linux, but has /dev/lxss; must be WSL 1
|
||||
return platform.system() == 'Linux' and stat.S_ISCHR(os.stat('/dev/lxss').st_mode)
|
||||
except:
|
||||
# Couldn't stat /dev/lxss special device; not WSL1
|
||||
return False
|
||||
|
||||
def _hostPlatformAlwaysDrivesUartRts(self):
|
||||
# OS-X/Windows seems to have a bug in its CP21xx serial drivers. It ignores that we asked for no RTSCTS
|
||||
# control and will always drive RTS either high or low (rather than letting the CP102 leave
|
||||
# it as an open-collector floating pin).
|
||||
# TODO: When WSL2 supports USB passthrough, this will get messier. If/when WSL2 gets virtual serial
|
||||
# ports that "share" the Windows serial port (and thus the Windows drivers), this code will need to be
|
||||
# updated to reflect that as well -- or if T-Beams get made with an alternate USB to UART bridge that has
|
||||
# a less buggy driver.
|
||||
return platform.system() != 'Linux' or self._isWsl1()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.serial_interface.SerialInterface"><code class="flex name class">
|
||||
<span>class <span class="ident">SerialInterface</span></span>
|
||||
<span>(</span><span>devPath=None, debugOut=None, noProto=False, connectNow=True)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Interface class for meshtastic devices over a serial link</p>
|
||||
<p>Constructor, opens a connection to a specified serial port, or if unspecified try to
|
||||
find one Meshtastic device by probing</p>
|
||||
<p>Keyword Arguments:
|
||||
devPath {string} – A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
|
||||
debugOut {stream} – If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None})</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class SerialInterface(StreamInterface):
|
||||
"""Interface class for meshtastic devices over a serial link"""
|
||||
|
||||
def __init__(self, devPath=None, debugOut=None, noProto=False, connectNow=True):
|
||||
"""Constructor, opens a connection to a specified serial port, or if unspecified try to
|
||||
find one Meshtastic device by probing
|
||||
|
||||
Keyword Arguments:
|
||||
devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
|
||||
debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None})
|
||||
"""
|
||||
|
||||
if devPath is None:
|
||||
ports = meshtastic.util.findPorts()
|
||||
logging.debug(f"ports:{ports}")
|
||||
if len(ports) == 0:
|
||||
meshtastic.util.our_exit("Warning: No Meshtastic devices detected.")
|
||||
elif len(ports) > 1:
|
||||
message = "Warning: Multiple serial ports were detected so one serial port must be specified with the '--port'.\n"
|
||||
message += f" Ports detected:{ports}"
|
||||
meshtastic.util.our_exit(message)
|
||||
else:
|
||||
devPath = ports[0]
|
||||
|
||||
logging.debug(f"Connecting to {devPath}")
|
||||
|
||||
# Note: we provide None for port here, because we will be opening it later
|
||||
self.stream = serial.Serial(
|
||||
None, 921600, exclusive=True, timeout=0.5, write_timeout=0)
|
||||
|
||||
# rts=False Needed to prevent TBEAMs resetting on OSX, because rts is connected to reset
|
||||
self.stream.port = devPath
|
||||
|
||||
# HACK: If the platform driving the serial port is unable to leave the RTS pin in high-impedance
|
||||
# mode, set RTS to false so that the device platform won't be reset spuriously.
|
||||
# Linux does this properly, so don't apply this hack on Linux (because it makes the reset button not work).
|
||||
if self._hostPlatformAlwaysDrivesUartRts():
|
||||
self.stream.rts = False
|
||||
self.stream.open()
|
||||
|
||||
StreamInterface.__init__(
|
||||
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow)
|
||||
|
||||
"""true if platform driving the serial port is Windows Subsystem for Linux 1."""
|
||||
def _isWsl1(self):
|
||||
# WSL1 identifies itself as Linux, but has a special char device at /dev/lxss for use with session control,
|
||||
# e.g. /init. We should treat WSL1 as Windows for the RTS-driving hack because the underlying platfrom
|
||||
# serial driver for the CP21xx still exhibits the buggy behavior.
|
||||
# WSL2 is not covered here, as it does not (as of 2021-May-25) support the appropriate functionality to
|
||||
# share or pass-through serial ports.
|
||||
try:
|
||||
# Claims to be Linux, but has /dev/lxss; must be WSL 1
|
||||
return platform.system() == 'Linux' and stat.S_ISCHR(os.stat('/dev/lxss').st_mode)
|
||||
except:
|
||||
# Couldn't stat /dev/lxss special device; not WSL1
|
||||
return False
|
||||
|
||||
def _hostPlatformAlwaysDrivesUartRts(self):
|
||||
# OS-X/Windows seems to have a bug in its CP21xx serial drivers. It ignores that we asked for no RTSCTS
|
||||
# control and will always drive RTS either high or low (rather than letting the CP102 leave
|
||||
# it as an open-collector floating pin).
|
||||
# TODO: When WSL2 supports USB passthrough, this will get messier. If/when WSL2 gets virtual serial
|
||||
# ports that "share" the Windows serial port (and thus the Windows drivers), this code will need to be
|
||||
# updated to reflect that as well -- or if T-Beams get made with an alternate USB to UART bridge that has
|
||||
# a less buggy driver.
|
||||
return platform.system() != 'Linux' or self._isWsl1()</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li><a title="meshtastic.stream_interface.StreamInterface" href="stream_interface.html#meshtastic.stream_interface.StreamInterface">StreamInterface</a></li>
|
||||
<li><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></li>
|
||||
</ul>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.serial_interface.SerialInterface._hostPlatformAlwaysDrivesUartRts"><code class="name flex">
|
||||
<span>def <span class="ident">_hostPlatformAlwaysDrivesUartRts</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _hostPlatformAlwaysDrivesUartRts(self):
|
||||
# OS-X/Windows seems to have a bug in its CP21xx serial drivers. It ignores that we asked for no RTSCTS
|
||||
# control and will always drive RTS either high or low (rather than letting the CP102 leave
|
||||
# it as an open-collector floating pin).
|
||||
# TODO: When WSL2 supports USB passthrough, this will get messier. If/when WSL2 gets virtual serial
|
||||
# ports that "share" the Windows serial port (and thus the Windows drivers), this code will need to be
|
||||
# updated to reflect that as well -- or if T-Beams get made with an alternate USB to UART bridge that has
|
||||
# a less buggy driver.
|
||||
return platform.system() != 'Linux' or self._isWsl1()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.serial_interface.SerialInterface._isWsl1"><code class="name flex">
|
||||
<span>def <span class="ident">_isWsl1</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _isWsl1(self):
|
||||
# WSL1 identifies itself as Linux, but has a special char device at /dev/lxss for use with session control,
|
||||
# e.g. /init. We should treat WSL1 as Windows for the RTS-driving hack because the underlying platfrom
|
||||
# serial driver for the CP21xx still exhibits the buggy behavior.
|
||||
# WSL2 is not covered here, as it does not (as of 2021-May-25) support the appropriate functionality to
|
||||
# share or pass-through serial ports.
|
||||
try:
|
||||
# Claims to be Linux, but has /dev/lxss; must be WSL 1
|
||||
return platform.system() == 'Linux' and stat.S_ISCHR(os.stat('/dev/lxss').st_mode)
|
||||
except:
|
||||
# Couldn't stat /dev/lxss special device; not WSL1
|
||||
return False</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Inherited members</h3>
|
||||
<ul class="hlist">
|
||||
<li><code><b><a title="meshtastic.stream_interface.StreamInterface" href="stream_interface.html#meshtastic.stream_interface.StreamInterface">StreamInterface</a></b></code>:
|
||||
<ul class="hlist">
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._StreamInterface__reader" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._StreamInterface__reader">_StreamInterface__reader</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._connected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._connected">_connected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._disconnected" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._disconnected">_disconnected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._fixupPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._fixupPosition">_fixupPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._generatePacketId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._generatePacketId">_generatePacketId</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._getOrCreateByNum" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._getOrCreateByNum">_getOrCreateByNum</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handleConfigComplete" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleConfigComplete">_handleConfigComplete</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handleFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleFromRadio">_handleFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handlePacketFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio">_handlePacketFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._nodeNumToId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._nodeNumToId">_nodeNumToId</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._readBytes" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._readBytes">_readBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendDisconnect" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendDisconnect">_sendDisconnect</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendPacket" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendPacket">_sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendToRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadio">_sendToRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendToRadioImpl" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadioImpl">_sendToRadioImpl</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._startConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startConfig">_startConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._startHeartbeat" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startHeartbeat">_startHeartbeat</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._waitConnected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._waitConnected">_waitConnected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._writeBytes" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._writeBytes">_writeBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.close" href="stream_interface.html#meshtastic.stream_interface.StreamInterface.close">close</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.connect" href="stream_interface.html#meshtastic.stream_interface.StreamInterface.connect">connect</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getLongName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getLongName">getLongName</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getMyNodeInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyNodeInfo">getMyNodeInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getMyUser" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyUser">getMyUser</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getNode" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getNode">getNode</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getShortName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getShortName">getShortName</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendData" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendData">sendData</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendText" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.showInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showInfo">showInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.showNodes" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showNodes">showNodes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.waitForConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.serial_interface.SerialInterface" href="#meshtastic.serial_interface.SerialInterface">SerialInterface</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.serial_interface.SerialInterface._hostPlatformAlwaysDrivesUartRts" href="#meshtastic.serial_interface.SerialInterface._hostPlatformAlwaysDrivesUartRts">_hostPlatformAlwaysDrivesUartRts</a></code></li>
|
||||
<li><code><a title="meshtastic.serial_interface.SerialInterface._isWsl1" href="#meshtastic.serial_interface.SerialInterface._isWsl1">_isWsl1</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,465 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.storeforward_pb2 API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.storeforward_pb2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python"># -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: storeforward.proto
|
||||
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='storeforward.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_options=b'\n\023com.geeksville.meshB\025StoreAndForwardProtosH\003Z!github.com/meshtastic/gomeshproto',
|
||||
serialized_pb=b'\n\x12storeforward.proto\"\xe7\x04\n\x0fStoreAndForward\x12,\n\x02rr\x18\x01 \x01(\x0e\x32 .StoreAndForward.RequestResponse\x12*\n\x05stats\x18\x02 \x01(\x0b\x32\x1b.StoreAndForward.Statistics\x12)\n\x07history\x18\x03 \x01(\x0b\x32\x18.StoreAndForward.History\x1a\xc6\x01\n\nStatistics\x12\x15\n\rMessagesTotal\x18\x01 \x01(\r\x12\x15\n\rMessagesSaved\x18\x02 \x01(\r\x12\x13\n\x0bMessagesMax\x18\x03 \x01(\r\x12\x0e\n\x06UpTime\x18\x04 \x01(\r\x12\x10\n\x08Requests\x18\x05 \x01(\r\x12\x17\n\x0fRequestsHistory\x18\x06 \x01(\r\x12\x11\n\tHeartbeat\x18\x07 \x01(\x08\x12\x11\n\tReturnMax\x18\x08 \x01(\r\x12\x14\n\x0cReturnWindow\x18\t \x01(\r\x1a\x32\n\x07History\x12\x17\n\x0fHistoryMessages\x18\x01 \x01(\r\x12\x0e\n\x06Window\x18\x02 \x01(\r\"\xd1\x01\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x10\n\x0c\x43LIENT_ERROR\x10\x65\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x66\x12\x10\n\x0c\x43LIENT_STATS\x10g\x12\x0f\n\x0b\x43LIENT_PING\x10h\x12\x0f\n\x0b\x43LIENT_PONG\x10iBQ\n\x13\x63om.geeksville.meshB\x15StoreAndForwardProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3'
|
||||
)
|
||||
|
||||
|
||||
|
||||
_STOREANDFORWARD_REQUESTRESPONSE = _descriptor.EnumDescriptor(
|
||||
name='RequestResponse',
|
||||
full_name='StoreAndForward.RequestResponse',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='UNSET', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTER_ERROR', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTER_HEARTBEAT', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTER_PING', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTER_PONG', index=4, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ROUTER_BUSY', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CLIENT_ERROR', index=6, number=101,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CLIENT_HISTORY', index=7, number=102,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CLIENT_STATS', index=8, number=103,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CLIENT_PING', index=9, number=104,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CLIENT_PONG', index=10, number=105,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=429,
|
||||
serialized_end=638,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_STOREANDFORWARD_REQUESTRESPONSE)
|
||||
|
||||
|
||||
_STOREANDFORWARD_STATISTICS = _descriptor.Descriptor(
|
||||
name='Statistics',
|
||||
full_name='StoreAndForward.Statistics',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='MessagesTotal', full_name='StoreAndForward.Statistics.MessagesTotal', index=0,
|
||||
number=1, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='MessagesSaved', full_name='StoreAndForward.Statistics.MessagesSaved', index=1,
|
||||
number=2, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='MessagesMax', full_name='StoreAndForward.Statistics.MessagesMax', index=2,
|
||||
number=3, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='UpTime', full_name='StoreAndForward.Statistics.UpTime', index=3,
|
||||
number=4, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Requests', full_name='StoreAndForward.Statistics.Requests', index=4,
|
||||
number=5, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='RequestsHistory', full_name='StoreAndForward.Statistics.RequestsHistory', index=5,
|
||||
number=6, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Heartbeat', full_name='StoreAndForward.Statistics.Heartbeat', index=6,
|
||||
number=7, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='ReturnMax', full_name='StoreAndForward.Statistics.ReturnMax', index=7,
|
||||
number=8, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='ReturnWindow', full_name='StoreAndForward.Statistics.ReturnWindow', index=8,
|
||||
number=9, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=176,
|
||||
serialized_end=374,
|
||||
)
|
||||
|
||||
_STOREANDFORWARD_HISTORY = _descriptor.Descriptor(
|
||||
name='History',
|
||||
full_name='StoreAndForward.History',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='HistoryMessages', full_name='StoreAndForward.History.HistoryMessages', index=0,
|
||||
number=1, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Window', full_name='StoreAndForward.History.Window', index=1,
|
||||
number=2, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=376,
|
||||
serialized_end=426,
|
||||
)
|
||||
|
||||
_STOREANDFORWARD = _descriptor.Descriptor(
|
||||
name='StoreAndForward',
|
||||
full_name='StoreAndForward',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='rr', full_name='StoreAndForward.rr', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='stats', full_name='StoreAndForward.stats', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='history', full_name='StoreAndForward.history', index=2,
|
||||
number=3, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[_STOREANDFORWARD_STATISTICS, _STOREANDFORWARD_HISTORY, ],
|
||||
enum_types=[
|
||||
_STOREANDFORWARD_REQUESTRESPONSE,
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=23,
|
||||
serialized_end=638,
|
||||
)
|
||||
|
||||
_STOREANDFORWARD_STATISTICS.containing_type = _STOREANDFORWARD
|
||||
_STOREANDFORWARD_HISTORY.containing_type = _STOREANDFORWARD
|
||||
_STOREANDFORWARD.fields_by_name['rr'].enum_type = _STOREANDFORWARD_REQUESTRESPONSE
|
||||
_STOREANDFORWARD.fields_by_name['stats'].message_type = _STOREANDFORWARD_STATISTICS
|
||||
_STOREANDFORWARD.fields_by_name['history'].message_type = _STOREANDFORWARD_HISTORY
|
||||
_STOREANDFORWARD_REQUESTRESPONSE.containing_type = _STOREANDFORWARD
|
||||
DESCRIPTOR.message_types_by_name['StoreAndForward'] = _STOREANDFORWARD
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
StoreAndForward = _reflection.GeneratedProtocolMessageType('StoreAndForward', (_message.Message,), {
|
||||
|
||||
'Statistics' : _reflection.GeneratedProtocolMessageType('Statistics', (_message.Message,), {
|
||||
'DESCRIPTOR' : _STOREANDFORWARD_STATISTICS,
|
||||
'__module__' : 'storeforward_pb2'
|
||||
# @@protoc_insertion_point(class_scope:StoreAndForward.Statistics)
|
||||
})
|
||||
,
|
||||
|
||||
'History' : _reflection.GeneratedProtocolMessageType('History', (_message.Message,), {
|
||||
'DESCRIPTOR' : _STOREANDFORWARD_HISTORY,
|
||||
'__module__' : 'storeforward_pb2'
|
||||
# @@protoc_insertion_point(class_scope:StoreAndForward.History)
|
||||
})
|
||||
,
|
||||
'DESCRIPTOR' : _STOREANDFORWARD,
|
||||
'__module__' : 'storeforward_pb2'
|
||||
# @@protoc_insertion_point(class_scope:StoreAndForward)
|
||||
})
|
||||
_sym_db.RegisterMessage(StoreAndForward)
|
||||
_sym_db.RegisterMessage(StoreAndForward.Statistics)
|
||||
_sym_db.RegisterMessage(StoreAndForward.History)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward"><code class="flex name class">
|
||||
<span>class <span class="ident">StoreAndForward</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>google.protobuf.pyext._message.CMessage</li>
|
||||
<li>google.protobuf.message.Message</li>
|
||||
</ul>
|
||||
<h3>Class variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_ERROR"><code class="name">var <span class="ident">CLIENT_ERROR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_HISTORY"><code class="name">var <span class="ident">CLIENT_HISTORY</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PING"><code class="name">var <span class="ident">CLIENT_PING</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PONG"><code class="name">var <span class="ident">CLIENT_PONG</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_STATS"><code class="name">var <span class="ident">CLIENT_STATS</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.History"><code class="name">var <span class="ident">History</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_BUSY"><code class="name">var <span class="ident">ROUTER_BUSY</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_ERROR"><code class="name">var <span class="ident">ROUTER_ERROR</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_HEARTBEAT"><code class="name">var <span class="ident">ROUTER_HEARTBEAT</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PING"><code class="name">var <span class="ident">ROUTER_PING</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PONG"><code class="name">var <span class="ident">ROUTER_PONG</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.RequestResponse"><code class="name">var <span class="ident">RequestResponse</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.Statistics"><code class="name">var <span class="ident">Statistics</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A ProtocolMessage</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.UNSET"><code class="name">var <span class="ident">UNSET</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Instance variables</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.history"><code class="name">var <span class="ident">history</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field StoreAndForward.history</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.rr"><code class="name">var <span class="ident">rr</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field StoreAndForward.rr</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.storeforward_pb2.StoreAndForward.stats"><code class="name">var <span class="ident">stats</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Field StoreAndForward.stats</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.storeforward_pb2.StoreAndForward" href="#meshtastic.storeforward_pb2.StoreAndForward">StoreAndForward</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_ERROR" href="#meshtastic.storeforward_pb2.StoreAndForward.CLIENT_ERROR">CLIENT_ERROR</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_HISTORY" href="#meshtastic.storeforward_pb2.StoreAndForward.CLIENT_HISTORY">CLIENT_HISTORY</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PING" href="#meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PING">CLIENT_PING</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PONG" href="#meshtastic.storeforward_pb2.StoreAndForward.CLIENT_PONG">CLIENT_PONG</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.CLIENT_STATS" href="#meshtastic.storeforward_pb2.StoreAndForward.CLIENT_STATS">CLIENT_STATS</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.DESCRIPTOR" href="#meshtastic.storeforward_pb2.StoreAndForward.DESCRIPTOR">DESCRIPTOR</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.History" href="#meshtastic.storeforward_pb2.StoreAndForward.History">History</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_BUSY" href="#meshtastic.storeforward_pb2.StoreAndForward.ROUTER_BUSY">ROUTER_BUSY</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_ERROR" href="#meshtastic.storeforward_pb2.StoreAndForward.ROUTER_ERROR">ROUTER_ERROR</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_HEARTBEAT" href="#meshtastic.storeforward_pb2.StoreAndForward.ROUTER_HEARTBEAT">ROUTER_HEARTBEAT</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PING" href="#meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PING">ROUTER_PING</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PONG" href="#meshtastic.storeforward_pb2.StoreAndForward.ROUTER_PONG">ROUTER_PONG</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.RequestResponse" href="#meshtastic.storeforward_pb2.StoreAndForward.RequestResponse">RequestResponse</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.Statistics" href="#meshtastic.storeforward_pb2.StoreAndForward.Statistics">Statistics</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.UNSET" href="#meshtastic.storeforward_pb2.StoreAndForward.UNSET">UNSET</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.history" href="#meshtastic.storeforward_pb2.StoreAndForward.history">history</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.rr" href="#meshtastic.storeforward_pb2.StoreAndForward.rr">rr</a></code></li>
|
||||
<li><code><a title="meshtastic.storeforward_pb2.StoreAndForward.stats" href="#meshtastic.storeforward_pb2.StoreAndForward.stats">stats</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,665 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.stream_interface API documentation</title>
|
||||
<meta name="description" content="Stream Interface base class" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.stream_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Stream Interface base class</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Stream Interface base class
|
||||
"""
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import serial
|
||||
|
||||
|
||||
from .mesh_interface import MeshInterface
|
||||
from .util import stripnl
|
||||
|
||||
|
||||
START1 = 0x94
|
||||
START2 = 0xc3
|
||||
HEADER_LEN = 4
|
||||
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):
|
||||
"""Constructor, opens a connection to self.stream
|
||||
|
||||
Keyword Arguments:
|
||||
debugOut {stream} -- If a stream is provided, any debug serial output from the
|
||||
device will be emitted to that stream. (default: {None})
|
||||
|
||||
Raises:
|
||||
Exception: [description]
|
||||
Exception: [description]
|
||||
"""
|
||||
|
||||
if not hasattr(self, 'stream') and not noProto:
|
||||
raise Exception(
|
||||
"StreamInterface is now abstract (to update existing code create SerialInterface instead)")
|
||||
self._rxBuf = bytes() # empty
|
||||
self._wantExit = False
|
||||
|
||||
# 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)
|
||||
|
||||
# Start the reader thread after superclass constructor completes init
|
||||
if connectNow:
|
||||
self.connect()
|
||||
if not noProto:
|
||||
self.waitForConfig()
|
||||
|
||||
def connect(self):
|
||||
"""Connect to our radio
|
||||
|
||||
Normally this is called automatically by the constructor, but if you
|
||||
passed in connectNow=False you can manually start the reading thread later.
|
||||
"""
|
||||
|
||||
# Send some bogus UART characters to force a sleeping device to wake, and
|
||||
# if the reading statemachine was parsing a bad packet make sure
|
||||
# we write enought start bytes to force it to resync (we don't use START1
|
||||
# because we want to ensure it is looking for START1)
|
||||
p = bytearray([START2] * 32)
|
||||
self._writeBytes(p)
|
||||
time.sleep(0.1) # wait 100ms to give device time to start running
|
||||
|
||||
self._rxThread.start()
|
||||
|
||||
self._startConfig()
|
||||
|
||||
if not self.noProto: # Wait for the db download if using the protocol
|
||||
self._waitConnected()
|
||||
|
||||
def _disconnected(self):
|
||||
"""We override the superclass implementation to close our port"""
|
||||
MeshInterface._disconnected(self)
|
||||
|
||||
logging.debug("Closing our port")
|
||||
# pylint: disable=E0203
|
||||
if not self.stream is None:
|
||||
# pylint: disable=E0203
|
||||
self.stream.close()
|
||||
# pylint: disable=W0201
|
||||
self.stream = None
|
||||
|
||||
def _writeBytes(self, b):
|
||||
"""Write an array of bytes to our stream and flush"""
|
||||
if self.stream: # ignore writes when stream is closed
|
||||
self.stream.write(b)
|
||||
self.stream.flush()
|
||||
|
||||
def _readBytes(self, length):
|
||||
"""Read an array of bytes from our stream"""
|
||||
if self.stream:
|
||||
return self.stream.read(length)
|
||||
else:
|
||||
return None
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
logging.debug(f"Sending: {stripnl(toRadio)}")
|
||||
b = toRadio.SerializeToString()
|
||||
bufLen = len(b)
|
||||
# We convert into a string, because the TCP code doesn't work with byte arrays
|
||||
header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
|
||||
logging.debug(f'sending header:{header} b:{b}')
|
||||
self._writeBytes(header + b)
|
||||
|
||||
def close(self):
|
||||
"""Close a connection to the device"""
|
||||
logging.debug("Closing stream")
|
||||
MeshInterface.close(self)
|
||||
# pyserial cancel_read doesn't seem to work, therefore we ask the
|
||||
# reader thread to close things for us
|
||||
self._wantExit = True
|
||||
if self._rxThread != threading.current_thread():
|
||||
self._rxThread.join() # wait for it to exit
|
||||
|
||||
def __reader(self):
|
||||
"""The reader thread that reads bytes from our stream"""
|
||||
logging.debug('in __reader()')
|
||||
empty = bytes()
|
||||
|
||||
try:
|
||||
while not self._wantExit:
|
||||
logging.debug("reading character")
|
||||
b = self._readBytes(1)
|
||||
logging.debug("In reader loop")
|
||||
#logging.debug(f"read returned {b}")
|
||||
if len(b) > 0:
|
||||
c = b[0]
|
||||
#logging.debug(f'c:{c}')
|
||||
ptr = len(self._rxBuf)
|
||||
|
||||
# Assume we want to append this byte, fixme use bytearray instead
|
||||
self._rxBuf = self._rxBuf + b
|
||||
|
||||
if ptr == 0: # looking for START1
|
||||
if c != START1:
|
||||
self._rxBuf = empty # failed to find start
|
||||
if self.debugOut is not None:
|
||||
try:
|
||||
self.debugOut.write(b.decode("utf-8"))
|
||||
except:
|
||||
self.debugOut.write('?')
|
||||
|
||||
elif ptr == 1: # looking for START2
|
||||
if c != START2:
|
||||
self._rxBuf = empty # failed to find start2
|
||||
elif ptr >= HEADER_LEN - 1: # we've at least got a header
|
||||
#logging.debug('at least we received a header')
|
||||
# big endian length follows header
|
||||
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
|
||||
|
||||
if ptr == HEADER_LEN - 1: # we _just_ finished reading the header, validate length
|
||||
if packetlen > MAX_TO_FROM_RADIO_SIZE:
|
||||
self._rxBuf = empty # length was out out bounds, restart
|
||||
|
||||
if len(self._rxBuf) != 0 and ptr + 1 >= packetlen + HEADER_LEN:
|
||||
try:
|
||||
self._handleFromRadio(self._rxBuf[HEADER_LEN:])
|
||||
except Exception as ex:
|
||||
logging.error(f"Error while handling message from radio {ex}")
|
||||
traceback.print_exc()
|
||||
self._rxBuf = empty
|
||||
else:
|
||||
# logging.debug(f"timeout")
|
||||
pass
|
||||
except serial.SerialException as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.warning(f"Meshtastic serial port disconnected, disconnecting... {ex}")
|
||||
except OSError as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}")
|
||||
except Exception as ex:
|
||||
logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}")
|
||||
finally:
|
||||
logging.debug("reader is exiting")
|
||||
self._disconnected()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface"><code class="flex name class">
|
||||
<span>class <span class="ident">StreamInterface</span></span>
|
||||
<span>(</span><span>debugOut=None, noProto=False, connectNow=True)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Interface class for meshtastic devices over a stream link (serial, TCP, etc)</p>
|
||||
<p>Constructor, opens a connection to self.stream</p>
|
||||
<p>Keyword Arguments:
|
||||
debugOut {stream} – If a stream is provided, any debug serial output from the
|
||||
device will be emitted to that stream. (default: {None})</p>
|
||||
<h2 id="raises">Raises</h2>
|
||||
<dl>
|
||||
<dt><code>Exception</code></dt>
|
||||
<dd>[description]</dd>
|
||||
<dt><code>Exception</code></dt>
|
||||
<dd>[description]</dd>
|
||||
</dl></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class StreamInterface(MeshInterface):
|
||||
"""Interface class for meshtastic devices over a stream link (serial, TCP, etc)"""
|
||||
|
||||
def __init__(self, debugOut=None, noProto=False, connectNow=True):
|
||||
"""Constructor, opens a connection to self.stream
|
||||
|
||||
Keyword Arguments:
|
||||
debugOut {stream} -- If a stream is provided, any debug serial output from the
|
||||
device will be emitted to that stream. (default: {None})
|
||||
|
||||
Raises:
|
||||
Exception: [description]
|
||||
Exception: [description]
|
||||
"""
|
||||
|
||||
if not hasattr(self, 'stream') and not noProto:
|
||||
raise Exception(
|
||||
"StreamInterface is now abstract (to update existing code create SerialInterface instead)")
|
||||
self._rxBuf = bytes() # empty
|
||||
self._wantExit = False
|
||||
|
||||
# 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)
|
||||
|
||||
# Start the reader thread after superclass constructor completes init
|
||||
if connectNow:
|
||||
self.connect()
|
||||
if not noProto:
|
||||
self.waitForConfig()
|
||||
|
||||
def connect(self):
|
||||
"""Connect to our radio
|
||||
|
||||
Normally this is called automatically by the constructor, but if you
|
||||
passed in connectNow=False you can manually start the reading thread later.
|
||||
"""
|
||||
|
||||
# Send some bogus UART characters to force a sleeping device to wake, and
|
||||
# if the reading statemachine was parsing a bad packet make sure
|
||||
# we write enought start bytes to force it to resync (we don't use START1
|
||||
# because we want to ensure it is looking for START1)
|
||||
p = bytearray([START2] * 32)
|
||||
self._writeBytes(p)
|
||||
time.sleep(0.1) # wait 100ms to give device time to start running
|
||||
|
||||
self._rxThread.start()
|
||||
|
||||
self._startConfig()
|
||||
|
||||
if not self.noProto: # Wait for the db download if using the protocol
|
||||
self._waitConnected()
|
||||
|
||||
def _disconnected(self):
|
||||
"""We override the superclass implementation to close our port"""
|
||||
MeshInterface._disconnected(self)
|
||||
|
||||
logging.debug("Closing our port")
|
||||
# pylint: disable=E0203
|
||||
if not self.stream is None:
|
||||
# pylint: disable=E0203
|
||||
self.stream.close()
|
||||
# pylint: disable=W0201
|
||||
self.stream = None
|
||||
|
||||
def _writeBytes(self, b):
|
||||
"""Write an array of bytes to our stream and flush"""
|
||||
if self.stream: # ignore writes when stream is closed
|
||||
self.stream.write(b)
|
||||
self.stream.flush()
|
||||
|
||||
def _readBytes(self, length):
|
||||
"""Read an array of bytes from our stream"""
|
||||
if self.stream:
|
||||
return self.stream.read(length)
|
||||
else:
|
||||
return None
|
||||
|
||||
def _sendToRadioImpl(self, toRadio):
|
||||
"""Send a ToRadio protobuf to the device"""
|
||||
logging.debug(f"Sending: {stripnl(toRadio)}")
|
||||
b = toRadio.SerializeToString()
|
||||
bufLen = len(b)
|
||||
# We convert into a string, because the TCP code doesn't work with byte arrays
|
||||
header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
|
||||
logging.debug(f'sending header:{header} b:{b}')
|
||||
self._writeBytes(header + b)
|
||||
|
||||
def close(self):
|
||||
"""Close a connection to the device"""
|
||||
logging.debug("Closing stream")
|
||||
MeshInterface.close(self)
|
||||
# pyserial cancel_read doesn't seem to work, therefore we ask the
|
||||
# reader thread to close things for us
|
||||
self._wantExit = True
|
||||
if self._rxThread != threading.current_thread():
|
||||
self._rxThread.join() # wait for it to exit
|
||||
|
||||
def __reader(self):
|
||||
"""The reader thread that reads bytes from our stream"""
|
||||
logging.debug('in __reader()')
|
||||
empty = bytes()
|
||||
|
||||
try:
|
||||
while not self._wantExit:
|
||||
logging.debug("reading character")
|
||||
b = self._readBytes(1)
|
||||
logging.debug("In reader loop")
|
||||
#logging.debug(f"read returned {b}")
|
||||
if len(b) > 0:
|
||||
c = b[0]
|
||||
#logging.debug(f'c:{c}')
|
||||
ptr = len(self._rxBuf)
|
||||
|
||||
# Assume we want to append this byte, fixme use bytearray instead
|
||||
self._rxBuf = self._rxBuf + b
|
||||
|
||||
if ptr == 0: # looking for START1
|
||||
if c != START1:
|
||||
self._rxBuf = empty # failed to find start
|
||||
if self.debugOut is not None:
|
||||
try:
|
||||
self.debugOut.write(b.decode("utf-8"))
|
||||
except:
|
||||
self.debugOut.write('?')
|
||||
|
||||
elif ptr == 1: # looking for START2
|
||||
if c != START2:
|
||||
self._rxBuf = empty # failed to find start2
|
||||
elif ptr >= HEADER_LEN - 1: # we've at least got a header
|
||||
#logging.debug('at least we received a header')
|
||||
# big endian length follows header
|
||||
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
|
||||
|
||||
if ptr == HEADER_LEN - 1: # we _just_ finished reading the header, validate length
|
||||
if packetlen > MAX_TO_FROM_RADIO_SIZE:
|
||||
self._rxBuf = empty # length was out out bounds, restart
|
||||
|
||||
if len(self._rxBuf) != 0 and ptr + 1 >= packetlen + HEADER_LEN:
|
||||
try:
|
||||
self._handleFromRadio(self._rxBuf[HEADER_LEN:])
|
||||
except Exception as ex:
|
||||
logging.error(f"Error while handling message from radio {ex}")
|
||||
traceback.print_exc()
|
||||
self._rxBuf = empty
|
||||
else:
|
||||
# logging.debug(f"timeout")
|
||||
pass
|
||||
except serial.SerialException as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.warning(f"Meshtastic serial port disconnected, disconnecting... {ex}")
|
||||
except OSError as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}")
|
||||
except Exception as ex:
|
||||
logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}")
|
||||
finally:
|
||||
logging.debug("reader is exiting")
|
||||
self._disconnected()</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></li>
|
||||
</ul>
|
||||
<h3>Subclasses</h3>
|
||||
<ul class="hlist">
|
||||
<li><a title="meshtastic.serial_interface.SerialInterface" href="serial_interface.html#meshtastic.serial_interface.SerialInterface">SerialInterface</a></li>
|
||||
<li><a title="meshtastic.tcp_interface.TCPInterface" href="tcp_interface.html#meshtastic.tcp_interface.TCPInterface">TCPInterface</a></li>
|
||||
</ul>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface._StreamInterface__reader"><code class="name flex">
|
||||
<span>def <span class="ident">_StreamInterface__reader</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>The reader thread that reads bytes from our stream</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def __reader(self):
|
||||
"""The reader thread that reads bytes from our stream"""
|
||||
logging.debug('in __reader()')
|
||||
empty = bytes()
|
||||
|
||||
try:
|
||||
while not self._wantExit:
|
||||
logging.debug("reading character")
|
||||
b = self._readBytes(1)
|
||||
logging.debug("In reader loop")
|
||||
#logging.debug(f"read returned {b}")
|
||||
if len(b) > 0:
|
||||
c = b[0]
|
||||
#logging.debug(f'c:{c}')
|
||||
ptr = len(self._rxBuf)
|
||||
|
||||
# Assume we want to append this byte, fixme use bytearray instead
|
||||
self._rxBuf = self._rxBuf + b
|
||||
|
||||
if ptr == 0: # looking for START1
|
||||
if c != START1:
|
||||
self._rxBuf = empty # failed to find start
|
||||
if self.debugOut is not None:
|
||||
try:
|
||||
self.debugOut.write(b.decode("utf-8"))
|
||||
except:
|
||||
self.debugOut.write('?')
|
||||
|
||||
elif ptr == 1: # looking for START2
|
||||
if c != START2:
|
||||
self._rxBuf = empty # failed to find start2
|
||||
elif ptr >= HEADER_LEN - 1: # we've at least got a header
|
||||
#logging.debug('at least we received a header')
|
||||
# big endian length follows header
|
||||
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
|
||||
|
||||
if ptr == HEADER_LEN - 1: # we _just_ finished reading the header, validate length
|
||||
if packetlen > MAX_TO_FROM_RADIO_SIZE:
|
||||
self._rxBuf = empty # length was out out bounds, restart
|
||||
|
||||
if len(self._rxBuf) != 0 and ptr + 1 >= packetlen + HEADER_LEN:
|
||||
try:
|
||||
self._handleFromRadio(self._rxBuf[HEADER_LEN:])
|
||||
except Exception as ex:
|
||||
logging.error(f"Error while handling message from radio {ex}")
|
||||
traceback.print_exc()
|
||||
self._rxBuf = empty
|
||||
else:
|
||||
# logging.debug(f"timeout")
|
||||
pass
|
||||
except serial.SerialException as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.warning(f"Meshtastic serial port disconnected, disconnecting... {ex}")
|
||||
except OSError as ex:
|
||||
if not self._wantExit: # We might intentionally get an exception during shutdown
|
||||
logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}")
|
||||
except Exception as ex:
|
||||
logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}")
|
||||
finally:
|
||||
logging.debug("reader is exiting")
|
||||
self._disconnected()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface._disconnected"><code class="name flex">
|
||||
<span>def <span class="ident">_disconnected</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>We override the superclass implementation to close our port</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _disconnected(self):
|
||||
"""We override the superclass implementation to close our port"""
|
||||
MeshInterface._disconnected(self)
|
||||
|
||||
logging.debug("Closing our port")
|
||||
# pylint: disable=E0203
|
||||
if not self.stream is None:
|
||||
# pylint: disable=E0203
|
||||
self.stream.close()
|
||||
# pylint: disable=W0201
|
||||
self.stream = None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface._readBytes"><code class="name flex">
|
||||
<span>def <span class="ident">_readBytes</span></span>(<span>self, length)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Read an array of bytes from our stream</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _readBytes(self, length):
|
||||
"""Read an array of bytes from our stream"""
|
||||
if self.stream:
|
||||
return self.stream.read(length)
|
||||
else:
|
||||
return None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface._writeBytes"><code class="name flex">
|
||||
<span>def <span class="ident">_writeBytes</span></span>(<span>self, b)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Write an array of bytes to our stream and flush</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _writeBytes(self, b):
|
||||
"""Write an array of bytes to our stream and flush"""
|
||||
if self.stream: # ignore writes when stream is closed
|
||||
self.stream.write(b)
|
||||
self.stream.flush()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface.close"><code class="name flex">
|
||||
<span>def <span class="ident">close</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Close a connection to the device</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def close(self):
|
||||
"""Close a connection to the device"""
|
||||
logging.debug("Closing stream")
|
||||
MeshInterface.close(self)
|
||||
# pyserial cancel_read doesn't seem to work, therefore we ask the
|
||||
# reader thread to close things for us
|
||||
self._wantExit = True
|
||||
if self._rxThread != threading.current_thread():
|
||||
self._rxThread.join() # wait for it to exit</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.stream_interface.StreamInterface.connect"><code class="name flex">
|
||||
<span>def <span class="ident">connect</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Connect to our radio</p>
|
||||
<p>Normally this is called automatically by the constructor, but if you
|
||||
passed in connectNow=False you can manually start the reading thread later.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def connect(self):
|
||||
"""Connect to our radio
|
||||
|
||||
Normally this is called automatically by the constructor, but if you
|
||||
passed in connectNow=False you can manually start the reading thread later.
|
||||
"""
|
||||
|
||||
# Send some bogus UART characters to force a sleeping device to wake, and
|
||||
# if the reading statemachine was parsing a bad packet make sure
|
||||
# we write enought start bytes to force it to resync (we don't use START1
|
||||
# because we want to ensure it is looking for START1)
|
||||
p = bytearray([START2] * 32)
|
||||
self._writeBytes(p)
|
||||
time.sleep(0.1) # wait 100ms to give device time to start running
|
||||
|
||||
self._rxThread.start()
|
||||
|
||||
self._startConfig()
|
||||
|
||||
if not self.noProto: # Wait for the db download if using the protocol
|
||||
self._waitConnected()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Inherited members</h3>
|
||||
<ul class="hlist">
|
||||
<li><code><b><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></b></code>:
|
||||
<ul class="hlist">
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._connected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._connected">_connected</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._fixupPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._fixupPosition">_fixupPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._generatePacketId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._generatePacketId">_generatePacketId</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._getOrCreateByNum" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._getOrCreateByNum">_getOrCreateByNum</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handleConfigComplete" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleConfigComplete">_handleConfigComplete</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handleFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleFromRadio">_handleFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio">_handlePacketFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._nodeNumToId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._nodeNumToId">_nodeNumToId</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendDisconnect" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendDisconnect">_sendDisconnect</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendPacket" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendPacket">_sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendToRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadio">_sendToRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._sendToRadioImpl" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadioImpl">_sendToRadioImpl</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._startConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startConfig">_startConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._startHeartbeat" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startHeartbeat">_startHeartbeat</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface._waitConnected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._waitConnected">_waitConnected</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getLongName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getLongName">getLongName</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getMyNodeInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyNodeInfo">getMyNodeInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getMyUser" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyUser">getMyUser</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getNode" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getNode">getNode</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.getShortName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getShortName">getShortName</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendData" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendData">sendData</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.sendText" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.showInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showInfo">showInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.showNodes" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showNodes">showNodes</a></code></li>
|
||||
<li><code><a title="meshtastic.mesh_interface.MeshInterface.waitForConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.stream_interface.StreamInterface" href="#meshtastic.stream_interface.StreamInterface">StreamInterface</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._StreamInterface__reader" href="#meshtastic.stream_interface.StreamInterface._StreamInterface__reader">_StreamInterface__reader</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._disconnected" href="#meshtastic.stream_interface.StreamInterface._disconnected">_disconnected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._readBytes" href="#meshtastic.stream_interface.StreamInterface._readBytes">_readBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._writeBytes" href="#meshtastic.stream_interface.StreamInterface._writeBytes">_writeBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.close" href="#meshtastic.stream_interface.StreamInterface.close">close</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.connect" href="#meshtastic.stream_interface.StreamInterface.connect">connect</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,270 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tcp_interface API documentation</title>
|
||||
<meta name="description" content="TCPInterface class for interfacing with http endpoint" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tcp_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>TCPInterface class for interfacing with http endpoint</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""TCPInterface class for interfacing with http endpoint
|
||||
"""
|
||||
import logging
|
||||
import socket
|
||||
from typing import AnyStr
|
||||
|
||||
from .stream_interface import StreamInterface
|
||||
|
||||
class TCPInterface(StreamInterface):
|
||||
"""Interface class for meshtastic devices over a TCP link"""
|
||||
|
||||
def __init__(self, hostname: AnyStr, debugOut=None, noProto=False,
|
||||
connectNow=True, portNumber=4403):
|
||||
"""Constructor, opens a connection to a specified IP address/hostname
|
||||
|
||||
Keyword Arguments:
|
||||
hostname {string} -- Hostname/IP address of the device to connect to
|
||||
"""
|
||||
|
||||
# Instead of wrapping as a stream, we use the native socket API
|
||||
# self.stream = sock.makefile('rw')
|
||||
self.stream = None
|
||||
|
||||
self.hostname = hostname
|
||||
self.portNumber = portNumber
|
||||
|
||||
if connectNow:
|
||||
logging.debug(f"Connecting to {hostname}")
|
||||
server_address = (hostname, portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock
|
||||
else:
|
||||
self.socket = None
|
||||
|
||||
StreamInterface.__init__(self, debugOut=debugOut, noProto=noProto,
|
||||
connectNow=connectNow)
|
||||
|
||||
def myConnect(self):
|
||||
"""Connect to socket"""
|
||||
server_address = (self.hostname, self.portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock
|
||||
|
||||
def close(self):
|
||||
"""Close a connection to the device"""
|
||||
logging.debug("Closing TCP stream")
|
||||
StreamInterface.close(self)
|
||||
# Sometimes the socket read might be blocked in the reader thread.
|
||||
# Therefore we force the shutdown by closing the socket here
|
||||
self._wantExit = True
|
||||
if not self.socket is None:
|
||||
try:
|
||||
self.socket.shutdown(socket.SHUT_RDWR)
|
||||
except:
|
||||
pass # Ignore errors in shutdown, because we might have a race with the server
|
||||
self.socket.close()
|
||||
|
||||
def _writeBytes(self, b):
|
||||
"""Write an array of bytes to our stream and flush"""
|
||||
self.socket.send(b)
|
||||
|
||||
def _readBytes(self, length):
|
||||
"""Read an array of bytes from our stream"""
|
||||
return self.socket.recv(length)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tcp_interface.TCPInterface"><code class="flex name class">
|
||||
<span>class <span class="ident">TCPInterface</span></span>
|
||||
<span>(</span><span>hostname: ~AnyStr, debugOut=None, noProto=False, connectNow=True, portNumber=4403)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Interface class for meshtastic devices over a TCP link</p>
|
||||
<p>Constructor, opens a connection to a specified IP address/hostname</p>
|
||||
<p>Keyword Arguments:
|
||||
hostname {string} – Hostname/IP address of the device to connect to</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class TCPInterface(StreamInterface):
|
||||
"""Interface class for meshtastic devices over a TCP link"""
|
||||
|
||||
def __init__(self, hostname: AnyStr, debugOut=None, noProto=False,
|
||||
connectNow=True, portNumber=4403):
|
||||
"""Constructor, opens a connection to a specified IP address/hostname
|
||||
|
||||
Keyword Arguments:
|
||||
hostname {string} -- Hostname/IP address of the device to connect to
|
||||
"""
|
||||
|
||||
# Instead of wrapping as a stream, we use the native socket API
|
||||
# self.stream = sock.makefile('rw')
|
||||
self.stream = None
|
||||
|
||||
self.hostname = hostname
|
||||
self.portNumber = portNumber
|
||||
|
||||
if connectNow:
|
||||
logging.debug(f"Connecting to {hostname}")
|
||||
server_address = (hostname, portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock
|
||||
else:
|
||||
self.socket = None
|
||||
|
||||
StreamInterface.__init__(self, debugOut=debugOut, noProto=noProto,
|
||||
connectNow=connectNow)
|
||||
|
||||
def myConnect(self):
|
||||
"""Connect to socket"""
|
||||
server_address = (self.hostname, self.portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock
|
||||
|
||||
def close(self):
|
||||
"""Close a connection to the device"""
|
||||
logging.debug("Closing TCP stream")
|
||||
StreamInterface.close(self)
|
||||
# Sometimes the socket read might be blocked in the reader thread.
|
||||
# Therefore we force the shutdown by closing the socket here
|
||||
self._wantExit = True
|
||||
if not self.socket is None:
|
||||
try:
|
||||
self.socket.shutdown(socket.SHUT_RDWR)
|
||||
except:
|
||||
pass # Ignore errors in shutdown, because we might have a race with the server
|
||||
self.socket.close()
|
||||
|
||||
def _writeBytes(self, b):
|
||||
"""Write an array of bytes to our stream and flush"""
|
||||
self.socket.send(b)
|
||||
|
||||
def _readBytes(self, length):
|
||||
"""Read an array of bytes from our stream"""
|
||||
return self.socket.recv(length)</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li><a title="meshtastic.stream_interface.StreamInterface" href="stream_interface.html#meshtastic.stream_interface.StreamInterface">StreamInterface</a></li>
|
||||
<li><a title="meshtastic.mesh_interface.MeshInterface" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface">MeshInterface</a></li>
|
||||
</ul>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.tcp_interface.TCPInterface.myConnect"><code class="name flex">
|
||||
<span>def <span class="ident">myConnect</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Connect to socket</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def myConnect(self):
|
||||
"""Connect to socket"""
|
||||
server_address = (self.hostname, self.portNumber)
|
||||
sock = socket.create_connection(server_address)
|
||||
self.socket = sock</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Inherited members</h3>
|
||||
<ul class="hlist">
|
||||
<li><code><b><a title="meshtastic.stream_interface.StreamInterface" href="stream_interface.html#meshtastic.stream_interface.StreamInterface">StreamInterface</a></b></code>:
|
||||
<ul class="hlist">
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._StreamInterface__reader" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._StreamInterface__reader">_StreamInterface__reader</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._connected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._connected">_connected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._disconnected" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._disconnected">_disconnected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._fixupPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._fixupPosition">_fixupPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._generatePacketId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._generatePacketId">_generatePacketId</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._getOrCreateByNum" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._getOrCreateByNum">_getOrCreateByNum</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handleConfigComplete" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleConfigComplete">_handleConfigComplete</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handleFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handleFromRadio">_handleFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._handlePacketFromRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._handlePacketFromRadio">_handlePacketFromRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._nodeNumToId" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._nodeNumToId">_nodeNumToId</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._readBytes" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._readBytes">_readBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendDisconnect" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendDisconnect">_sendDisconnect</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendPacket" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendPacket">_sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendToRadio" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadio">_sendToRadio</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._sendToRadioImpl" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._sendToRadioImpl">_sendToRadioImpl</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._startConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startConfig">_startConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._startHeartbeat" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._startHeartbeat">_startHeartbeat</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._waitConnected" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface._waitConnected">_waitConnected</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface._writeBytes" href="stream_interface.html#meshtastic.stream_interface.StreamInterface._writeBytes">_writeBytes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.close" href="stream_interface.html#meshtastic.stream_interface.StreamInterface.close">close</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.connect" href="stream_interface.html#meshtastic.stream_interface.StreamInterface.connect">connect</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getLongName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getLongName">getLongName</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getMyNodeInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyNodeInfo">getMyNodeInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getMyUser" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getMyUser">getMyUser</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getNode" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getNode">getNode</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.getShortName" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.getShortName">getShortName</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendData" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendData">sendData</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendPosition" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.sendText" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.showInfo" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showInfo">showInfo</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.showNodes" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.showNodes">showNodes</a></code></li>
|
||||
<li><code><a title="meshtastic.stream_interface.StreamInterface.waitForConfig" href="mesh_interface.html#meshtastic.mesh_interface.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.tcp_interface.TCPInterface" href="#meshtastic.tcp_interface.TCPInterface">TCPInterface</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tcp_interface.TCPInterface.myConnect" href="#meshtastic.tcp_interface.TCPInterface.myConnect">myConnect</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,544 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.test API documentation</title>
|
||||
<meta name="description" content="With two radios connected serially, send and receive test
|
||||
messages and report back if successful." />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>With two radios connected serially, send and receive test
|
||||
messages and report back if successful.</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""With two radios connected serially, send and receive test
|
||||
messages and report back if successful.
|
||||
"""
|
||||
import logging
|
||||
import time
|
||||
import sys
|
||||
import traceback
|
||||
from dotmap import DotMap
|
||||
from pubsub import pub
|
||||
import meshtastic.util
|
||||
from .__init__ import BROADCAST_NUM
|
||||
from .serial_interface import SerialInterface
|
||||
from .tcp_interface import TCPInterface
|
||||
|
||||
|
||||
"""The interfaces we are using for our tests"""
|
||||
interfaces = None
|
||||
|
||||
"""A list of all packets we received while the current test was running"""
|
||||
receivedPackets = None
|
||||
|
||||
testsRunning = False
|
||||
|
||||
testNumber = 0
|
||||
|
||||
sendingInterface = None
|
||||
|
||||
|
||||
def onReceive(packet, interface):
|
||||
"""Callback invoked when a packet arrives"""
|
||||
if sendingInterface == interface:
|
||||
pass
|
||||
# print("Ignoring sending interface")
|
||||
else:
|
||||
# print(f"From {interface.stream.port}: {packet}")
|
||||
p = DotMap(packet)
|
||||
|
||||
if p.decoded.portnum == "TEXT_MESSAGE_APP":
|
||||
# We only care a about clear text packets
|
||||
if receivedPackets is not None:
|
||||
receivedPackets.append(p)
|
||||
|
||||
|
||||
def onNode(node):
|
||||
"""Callback invoked when the node DB changes"""
|
||||
print(f"Node changed: {node}")
|
||||
|
||||
|
||||
def subscribe():
|
||||
"""Subscribe to the topics the user probably wants to see, prints output to stdout"""
|
||||
|
||||
pub.subscribe(onNode, "meshtastic.node")
|
||||
|
||||
|
||||
def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False):
|
||||
"""
|
||||
Sends one test packet between two nodes and then returns success or failure
|
||||
|
||||
Arguments:
|
||||
fromInterface {[type]} -- [description]
|
||||
toInterface {[type]} -- [description]
|
||||
|
||||
Returns:
|
||||
boolean -- True for success
|
||||
"""
|
||||
global receivedPackets
|
||||
receivedPackets = []
|
||||
fromNode = fromInterface.myInfo.my_node_num
|
||||
|
||||
if isBroadcast:
|
||||
toNode = BROADCAST_NUM
|
||||
else:
|
||||
toNode = toInterface.myInfo.my_node_num
|
||||
|
||||
logging.debug(
|
||||
f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}")
|
||||
global sendingInterface
|
||||
sendingInterface = fromInterface
|
||||
if not asBinary:
|
||||
fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=wantAck)
|
||||
else:
|
||||
fromInterface.sendData((f"Binary {testNumber}").encode(
|
||||
"utf-8"), toNode, wantAck=wantAck)
|
||||
for _ in range(60): # max of 60 secs before we timeout
|
||||
time.sleep(1)
|
||||
if len(receivedPackets) >= 1:
|
||||
return True
|
||||
return False # Failed to send
|
||||
|
||||
|
||||
def runTests(numTests=50, wantAck=False, maxFailures=0):
|
||||
"""Run the tests."""
|
||||
logging.info(f"Running {numTests} tests with wantAck={wantAck}")
|
||||
numFail = 0
|
||||
numSuccess = 0
|
||||
for _ in range(numTests):
|
||||
global testNumber
|
||||
testNumber = testNumber + 1
|
||||
isBroadcast = True
|
||||
# asBinary=(i % 2 == 0)
|
||||
success = testSend(
|
||||
interfaces[0], interfaces[1], isBroadcast, asBinary=False, wantAck=wantAck)
|
||||
if not success:
|
||||
numFail = numFail + 1
|
||||
logging.error(
|
||||
f"Test {testNumber} failed, expected packet not received ({numFail} failures so far)")
|
||||
else:
|
||||
numSuccess = numSuccess + 1
|
||||
logging.info(
|
||||
f"Test {testNumber} succeeded {numSuccess} successes {numFail} failures so far")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
if numFail > maxFailures:
|
||||
logging.error("Too many failures! Test failed!")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def testThread(numTests=50):
|
||||
"""Test thread"""
|
||||
logging.info("Found devices, starting tests...")
|
||||
result = runTests(numTests, wantAck=True)
|
||||
if result:
|
||||
# Run another test
|
||||
# Allow a few dropped packets
|
||||
result = runTests(numTests, wantAck=False, maxFailures=1)
|
||||
return result
|
||||
|
||||
|
||||
def onConnection(topic=pub.AUTO_TOPIC):
|
||||
"""Callback invoked when we connect/disconnect from a radio"""
|
||||
print(f"Connection changed: {topic.getName()}")
|
||||
|
||||
|
||||
def openDebugLog(portName):
|
||||
"""Open the debug log file"""
|
||||
debugname = "log" + portName.replace("/", "_")
|
||||
logging.info(f"Writing serial debugging to {debugname}")
|
||||
return open(debugname, 'w+', buffering=1, encoding='utf8')
|
||||
|
||||
|
||||
def testAll(numTests=5):
|
||||
"""
|
||||
Run a series of tests using devices we can find.
|
||||
This is called from the cli with the "--test" option.
|
||||
|
||||
"""
|
||||
ports = meshtastic.util.findPorts()
|
||||
if len(ports) < 2:
|
||||
meshtastic.util.our_exit("Warning: Must have at least two devices connected to USB.")
|
||||
|
||||
pub.subscribe(onConnection, "meshtastic.connection")
|
||||
pub.subscribe(onReceive, "meshtastic.receive")
|
||||
global interfaces
|
||||
interfaces = list(map(lambda port: SerialInterface(
|
||||
port, debugOut=openDebugLog(port), connectNow=True), ports))
|
||||
|
||||
logging.info("Ports opened, starting test")
|
||||
result = testThread(numTests)
|
||||
|
||||
for i in interfaces:
|
||||
i.close()
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def testSimulator():
|
||||
"""
|
||||
Assume that someone has launched meshtastic-native as a simulated node.
|
||||
Talk to that node over TCP, do some operations and if they are successful
|
||||
exit the process with a success code, else exit with a non zero exit code.
|
||||
|
||||
Run with
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
"""
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.info("Connecting to simulator on localhost!")
|
||||
try:
|
||||
iface = TCPInterface("localhost")
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.localNode.exitSimulator()
|
||||
iface.close()
|
||||
logging.info("Integration test successful!")
|
||||
except:
|
||||
print("Error while testing simulator:", sys.exc_info()[0])
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
sys.exit(0)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-variables">Global variables</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.interfaces"><code class="name">var <span class="ident">interfaces</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A list of all packets we received while the current test was running</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.onConnection"><code class="name flex">
|
||||
<span>def <span class="ident">onConnection</span></span>(<span>topic=pubsub.core.callables.AUTO_TOPIC)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Callback invoked when we connect/disconnect from a radio</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onConnection(topic=pub.AUTO_TOPIC):
|
||||
"""Callback invoked when we connect/disconnect from a radio"""
|
||||
print(f"Connection changed: {topic.getName()}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.onNode"><code class="name flex">
|
||||
<span>def <span class="ident">onNode</span></span>(<span>node)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Callback invoked when the node DB changes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onNode(node):
|
||||
"""Callback invoked when the node DB changes"""
|
||||
print(f"Node changed: {node}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.onReceive"><code class="name flex">
|
||||
<span>def <span class="ident">onReceive</span></span>(<span>packet, interface)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Callback invoked when a packet arrives</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onReceive(packet, interface):
|
||||
"""Callback invoked when a packet arrives"""
|
||||
if sendingInterface == interface:
|
||||
pass
|
||||
# print("Ignoring sending interface")
|
||||
else:
|
||||
# print(f"From {interface.stream.port}: {packet}")
|
||||
p = DotMap(packet)
|
||||
|
||||
if p.decoded.portnum == "TEXT_MESSAGE_APP":
|
||||
# We only care a about clear text packets
|
||||
if receivedPackets is not None:
|
||||
receivedPackets.append(p)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.openDebugLog"><code class="name flex">
|
||||
<span>def <span class="ident">openDebugLog</span></span>(<span>portName)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Open the debug log file</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def openDebugLog(portName):
|
||||
"""Open the debug log file"""
|
||||
debugname = "log" + portName.replace("/", "_")
|
||||
logging.info(f"Writing serial debugging to {debugname}")
|
||||
return open(debugname, 'w+', buffering=1, encoding='utf8')</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.runTests"><code class="name flex">
|
||||
<span>def <span class="ident">runTests</span></span>(<span>numTests=50, wantAck=False, maxFailures=0)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Run the tests.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def runTests(numTests=50, wantAck=False, maxFailures=0):
|
||||
"""Run the tests."""
|
||||
logging.info(f"Running {numTests} tests with wantAck={wantAck}")
|
||||
numFail = 0
|
||||
numSuccess = 0
|
||||
for _ in range(numTests):
|
||||
global testNumber
|
||||
testNumber = testNumber + 1
|
||||
isBroadcast = True
|
||||
# asBinary=(i % 2 == 0)
|
||||
success = testSend(
|
||||
interfaces[0], interfaces[1], isBroadcast, asBinary=False, wantAck=wantAck)
|
||||
if not success:
|
||||
numFail = numFail + 1
|
||||
logging.error(
|
||||
f"Test {testNumber} failed, expected packet not received ({numFail} failures so far)")
|
||||
else:
|
||||
numSuccess = numSuccess + 1
|
||||
logging.info(
|
||||
f"Test {testNumber} succeeded {numSuccess} successes {numFail} failures so far")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
if numFail > maxFailures:
|
||||
logging.error("Too many failures! Test failed!")
|
||||
return False
|
||||
return True</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.subscribe"><code class="name flex">
|
||||
<span>def <span class="ident">subscribe</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Subscribe to the topics the user probably wants to see, prints output to stdout</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def subscribe():
|
||||
"""Subscribe to the topics the user probably wants to see, prints output to stdout"""
|
||||
|
||||
pub.subscribe(onNode, "meshtastic.node")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.testAll"><code class="name flex">
|
||||
<span>def <span class="ident">testAll</span></span>(<span>numTests=5)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Run a series of tests using devices we can find.
|
||||
This is called from the cli with the "–test" option.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def testAll(numTests=5):
|
||||
"""
|
||||
Run a series of tests using devices we can find.
|
||||
This is called from the cli with the "--test" option.
|
||||
|
||||
"""
|
||||
ports = meshtastic.util.findPorts()
|
||||
if len(ports) < 2:
|
||||
meshtastic.util.our_exit("Warning: Must have at least two devices connected to USB.")
|
||||
|
||||
pub.subscribe(onConnection, "meshtastic.connection")
|
||||
pub.subscribe(onReceive, "meshtastic.receive")
|
||||
global interfaces
|
||||
interfaces = list(map(lambda port: SerialInterface(
|
||||
port, debugOut=openDebugLog(port), connectNow=True), ports))
|
||||
|
||||
logging.info("Ports opened, starting test")
|
||||
result = testThread(numTests)
|
||||
|
||||
for i in interfaces:
|
||||
i.close()
|
||||
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.testSend"><code class="name flex">
|
||||
<span>def <span class="ident">testSend</span></span>(<span>fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Sends one test packet between two nodes and then returns success or failure</p>
|
||||
<h2 id="arguments">Arguments</h2>
|
||||
<p>fromInterface {[type]} – [description]
|
||||
toInterface {[type]} – [description]</p>
|
||||
<h2 id="returns">Returns</h2>
|
||||
<p>boolean – True for success</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False):
|
||||
"""
|
||||
Sends one test packet between two nodes and then returns success or failure
|
||||
|
||||
Arguments:
|
||||
fromInterface {[type]} -- [description]
|
||||
toInterface {[type]} -- [description]
|
||||
|
||||
Returns:
|
||||
boolean -- True for success
|
||||
"""
|
||||
global receivedPackets
|
||||
receivedPackets = []
|
||||
fromNode = fromInterface.myInfo.my_node_num
|
||||
|
||||
if isBroadcast:
|
||||
toNode = BROADCAST_NUM
|
||||
else:
|
||||
toNode = toInterface.myInfo.my_node_num
|
||||
|
||||
logging.debug(
|
||||
f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}")
|
||||
global sendingInterface
|
||||
sendingInterface = fromInterface
|
||||
if not asBinary:
|
||||
fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=wantAck)
|
||||
else:
|
||||
fromInterface.sendData((f"Binary {testNumber}").encode(
|
||||
"utf-8"), toNode, wantAck=wantAck)
|
||||
for _ in range(60): # max of 60 secs before we timeout
|
||||
time.sleep(1)
|
||||
if len(receivedPackets) >= 1:
|
||||
return True
|
||||
return False # Failed to send</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.testSimulator"><code class="name flex">
|
||||
<span>def <span class="ident">testSimulator</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Assume that someone has launched meshtastic-native as a simulated node.
|
||||
Talk to that node over TCP, do some operations and if they are successful
|
||||
exit the process with a success code, else exit with a non zero exit code.</p>
|
||||
<p>Run with
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def testSimulator():
|
||||
"""
|
||||
Assume that someone has launched meshtastic-native as a simulated node.
|
||||
Talk to that node over TCP, do some operations and if they are successful
|
||||
exit the process with a success code, else exit with a non zero exit code.
|
||||
|
||||
Run with
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
"""
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.info("Connecting to simulator on localhost!")
|
||||
try:
|
||||
iface = TCPInterface("localhost")
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.localNode.exitSimulator()
|
||||
iface.close()
|
||||
logging.info("Integration test successful!")
|
||||
except:
|
||||
print("Error while testing simulator:", sys.exc_info()[0])
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
sys.exit(0)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.testThread"><code class="name flex">
|
||||
<span>def <span class="ident">testThread</span></span>(<span>numTests=50)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test thread</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def testThread(numTests=50):
|
||||
"""Test thread"""
|
||||
logging.info("Found devices, starting tests...")
|
||||
result = runTests(numTests, wantAck=True)
|
||||
if result:
|
||||
# Run another test
|
||||
# Allow a few dropped packets
|
||||
result = runTests(numTests, wantAck=False, maxFailures=1)
|
||||
return result</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-variables">Global variables</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.test.interfaces" href="#meshtastic.test.interfaces">interfaces</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.test.onConnection" href="#meshtastic.test.onConnection">onConnection</a></code></li>
|
||||
<li><code><a title="meshtastic.test.onNode" href="#meshtastic.test.onNode">onNode</a></code></li>
|
||||
<li><code><a title="meshtastic.test.onReceive" href="#meshtastic.test.onReceive">onReceive</a></code></li>
|
||||
<li><code><a title="meshtastic.test.openDebugLog" href="#meshtastic.test.openDebugLog">openDebugLog</a></code></li>
|
||||
<li><code><a title="meshtastic.test.runTests" href="#meshtastic.test.runTests">runTests</a></code></li>
|
||||
<li><code><a title="meshtastic.test.subscribe" href="#meshtastic.test.subscribe">subscribe</a></code></li>
|
||||
<li><code><a title="meshtastic.test.testAll" href="#meshtastic.test.testAll">testAll</a></code></li>
|
||||
<li><code><a title="meshtastic.test.testSend" href="#meshtastic.test.testSend">testSend</a></code></li>
|
||||
<li><code><a title="meshtastic.test.testSimulator" href="#meshtastic.test.testSimulator">testSimulator</a></code></li>
|
||||
<li><code><a title="meshtastic.test.testThread" href="#meshtastic.test.testThread">testThread</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,80 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.0" />
|
||||
<title>meshtastic.test API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
||||
<dl>
|
||||
<dt><code class="name"><a title="meshtastic.test.test_int" href="test_int.html">meshtastic.test.test_int</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic integration tests</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.test.test_mesh_interface" href="test_mesh_interface.html">meshtastic.test.test_mesh_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for node.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.test.test_smoke1" href="test_smoke1.html">meshtastic.test.test_smoke1</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic smoke tests with a single device</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.test.test_util" href="test_util.html">meshtastic.test.test_util</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for node.py</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="../index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.test.test_int" href="test_int.html">meshtastic.test.test_int</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_mesh_interface" href="test_mesh_interface.html">meshtastic.test.test_mesh_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1" href="test_smoke1.html">meshtastic.test.test_smoke1</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util" href="test_util.html">meshtastic.test.test_util</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,177 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.0" />
|
||||
<title>meshtastic.test.test_int API documentation</title>
|
||||
<meta name="description" content="Meshtastic integration tests" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test.test_int</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic integration tests</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic integration tests"""
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_no_args():
|
||||
"""Test without any args"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic')
|
||||
assert re.match(r'usage: meshtastic', out)
|
||||
assert return_value == 1
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_version():
|
||||
"""Test '--version'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --version')
|
||||
assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_help():
|
||||
"""Test '--help'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --help')
|
||||
assert re.match(r'usage: meshtastic ', out)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_support():
|
||||
"""Test '--support'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --support')
|
||||
assert re.search(r'System', out)
|
||||
assert re.search(r'Python', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.test_int.test_int_help"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_help</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–help'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_help():
|
||||
"""Test '--help'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --help')
|
||||
assert re.match(r'usage: meshtastic ', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_int.test_int_no_args"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_no_args</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test without any args</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_no_args():
|
||||
"""Test without any args"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic')
|
||||
assert re.match(r'usage: meshtastic', out)
|
||||
assert return_value == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_int.test_int_support"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_support</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–support'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_support():
|
||||
"""Test '--support'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --support')
|
||||
assert re.search(r'System', out)
|
||||
assert re.search(r'Python', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_int.test_int_version"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_version</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–version'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_version():
|
||||
"""Test '--version'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --version')
|
||||
assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.test" href="index.html">meshtastic.test</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.test.test_int.test_int_help" href="#meshtastic.test.test_int.test_int_help">test_int_help</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_int.test_int_no_args" href="#meshtastic.test.test_int.test_int_no_args">test_int_no_args</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_int.test_int_support" href="#meshtastic.test.test_int.test_int_support">test_int_support</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_int.test_int_version" href="#meshtastic.test.test_int.test_int_version">test_int_version</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,99 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.0" />
|
||||
<title>meshtastic.test.test_mesh_interface API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for node.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test.test_mesh_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for node.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for node.py"""
|
||||
|
||||
import pytest
|
||||
|
||||
from meshtastic.mesh_interface import MeshInterface
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_MeshInterface():
|
||||
"""Test that we instantiate a MeshInterface"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.test_mesh_interface.test_MeshInterface"><code class="name flex">
|
||||
<span>def <span class="ident">test_MeshInterface</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we instantiate a MeshInterface</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_MeshInterface():
|
||||
"""Test that we instantiate a MeshInterface"""
|
||||
iface = MeshInterface(noProto=True)
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.test" href="index.html">meshtastic.test</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.test.test_mesh_interface.test_MeshInterface" href="#meshtastic.test.test_mesh_interface.test_MeshInterface">test_MeshInterface</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,982 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.0" />
|
||||
<title>meshtastic.test.test_smoke1 API documentation</title>
|
||||
<meta name="description" content="Meshtastic smoke tests with a single device" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test.test_smoke1</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic smoke tests with a single device</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic smoke tests with a single device"""
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
import os
|
||||
|
||||
# Do not like using hard coded sleeps, but it probably makes
|
||||
# sense to pause for the radio at apprpriate times
|
||||
import pytest
|
||||
|
||||
import meshtastic
|
||||
|
||||
# seconds to pause after running a meshtastic command
|
||||
PAUSE_AFTER_COMMAND = 2
|
||||
PAUSE_AFTER_REBOOT = 7
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_reboot():
|
||||
"""Test reboot"""
|
||||
return_value, _ = subprocess.getstatusoutput('meshtastic --reboot')
|
||||
assert return_value == 0
|
||||
# pause for the radio to reset (10 seconds for the pause, and a few more seconds to be back up)
|
||||
time.sleep(18)
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_info():
|
||||
"""Test --info"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^My info', out, re.MULTILINE)
|
||||
assert re.search(r'^Nodes in mesh', out, re.MULTILINE)
|
||||
assert re.search(r'^Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'^Channels', out, re.MULTILINE)
|
||||
assert re.search(r'^ PRIMARY', out, re.MULTILINE)
|
||||
assert re.search(r'^Primary channel URL', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_debug():
|
||||
"""Test --debug"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info --debug')
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^DEBUG:root', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_seriallog_to_file():
|
||||
"""Test --seriallog to a file creates a file"""
|
||||
filename = 'tmpoutput.txt'
|
||||
if os.path.exists(f"{filename}"):
|
||||
os.remove(f"{filename}")
|
||||
return_value, _ = subprocess.getstatusoutput(f'meshtastic --info --seriallog {filename}')
|
||||
assert os.path.exists(f"{filename}")
|
||||
assert return_value == 0
|
||||
os.remove(f"{filename}")
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_qr():
|
||||
"""Test --qr"""
|
||||
filename = 'tmpqr'
|
||||
if os.path.exists(f"{filename}"):
|
||||
os.remove(f"{filename}")
|
||||
return_value, _ = subprocess.getstatusoutput(f'meshtastic --qr > {filename}')
|
||||
assert os.path.exists(f"{filename}")
|
||||
# not really testing that a valid qr code is created, just that the file size
|
||||
# is reasonably big enough for a qr code
|
||||
assert os.stat(f"{filename}").st_size > 20000
|
||||
assert return_value == 0
|
||||
os.remove(f"{filename}")
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_nodes():
|
||||
"""Test --nodes"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --nodes')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^│ N │ User', out, re.MULTILINE)
|
||||
assert re.search(r'^│ 1 │', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_send_hello():
|
||||
"""Test --sendtext hello"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --sendtext hello')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Sending text message hello to \^all', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_port():
|
||||
"""Test --port"""
|
||||
# first, get the ports
|
||||
ports = meshtastic.util.findPorts()
|
||||
# hopefully there is just one
|
||||
assert len(ports) == 1
|
||||
port = ports[0]
|
||||
return_value, out = subprocess.getstatusoutput(f'meshtastic --port {port} --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_set_is_router_true():
|
||||
"""Test --set is_router true"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router true')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set is_router to true', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
|
||||
assert re.search(r'^is_router: True', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_set_location_info():
|
||||
"""Test --setlat, --setlon and --setalt """
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --setlat 32.7767 --setlon -96.7970 --setalt 1337')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Fixing altitude', out, re.MULTILINE)
|
||||
assert re.search(r'^Fixing latitude', out, re.MULTILINE)
|
||||
assert re.search(r'^Fixing longitude', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out2 = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'1337', out2, re.MULTILINE)
|
||||
assert re.search(r'32.7767', out2, re.MULTILINE)
|
||||
assert re.search(r'-96.797', out2, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_set_is_router_false():
|
||||
"""Test --set is_router false"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router false')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set is_router to false', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
|
||||
assert re.search(r'^is_router: False', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_set_owner():
|
||||
"""Test --set-owner name"""
|
||||
# make sure the owner is not Joe
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-owner Bob')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting device owner to Bob', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'Owner: Joe', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-owner Joe')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting device owner to Joe', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Owner: Joe', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_set_team():
|
||||
"""Test --set-team """
|
||||
# unset the team
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CLEAR')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting team to CLEAR', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CYAN')
|
||||
assert re.search(r'Setting team to CYAN', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'CYAN', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_ch_values():
|
||||
"""Test --ch-longslow, --ch-longfast, --ch-mediumslow, --ch-mediumsfast,
|
||||
--ch-shortslow, and --ch-shortfast arguments
|
||||
"""
|
||||
exp = {
|
||||
'--ch-longslow': 'Bw125Cr48Sf4096',
|
||||
# TODO: not sure why these fail thru tests, but ok manually
|
||||
#'--ch-longfast': 'Bw31_25Cr48Sf512',
|
||||
#'--ch-mediumslow': 'Bw250Cr46Sf2048',
|
||||
#'--ch-mediumfast': 'Bw250Cr47Sf1024',
|
||||
# TODO '--ch-shortslow': '?',
|
||||
'--ch-shortfast': 'Bw500Cr45Sf128'
|
||||
}
|
||||
|
||||
for key, val in exp.items():
|
||||
print(key, val)
|
||||
return_value, out = subprocess.getstatusoutput(f'meshtastic {key}')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'Writing modified channels to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio (might reboot)
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(val, out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_ch_set_name():
|
||||
"""Test --ch-set name"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set name MyChannel')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set name to MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_ch_add_and_ch_del():
|
||||
"""Test --ch-add"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-add testing')
|
||||
assert re.search(r'Writing modified channels to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'SECONDARY', out, re.MULTILINE)
|
||||
assert re.search(r'testing', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-index 1 --ch-del')
|
||||
assert re.search(r'Deleting channel 1', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
# make sure the secondar channel is not there
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert not re.search(r'SECONDARY', out, re.MULTILINE)
|
||||
assert not re.search(r'testing', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_ch_set_modem_config():
|
||||
"""Test --ch-set modem_config"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config Bw31_25Cr48Sf512')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set modem_config to Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_seturl_default():
|
||||
"""Test --seturl with default value"""
|
||||
# set some channel value so we no longer have a default channel
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set name foo')
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
# ensure we no longer have a default primary channel
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search('CgUYAyIBAQ', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
url = "https://www.meshtastic.org/d/#CgUYAyIBAQ"
|
||||
return_value, out = subprocess.getstatusoutput(f"meshtastic --seturl {url}")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search('CgUYAyIBAQ', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_seturl_invalid_url():
|
||||
"""Test --seturl with invalid url"""
|
||||
# Note: This url is no longer a valid url.
|
||||
url = "https://www.meshtastic.org/c/#GAMiENTxuzogKQdZ8Lz_q89Oab8qB0RlZmF1bHQ="
|
||||
return_value, out = subprocess.getstatusoutput(f"meshtastic --seturl {url}")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search('Warning: There were no settings', out, re.MULTILINE)
|
||||
assert return_value == 1
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_configure():
|
||||
"""Test --configure"""
|
||||
_ , out = subprocess.getstatusoutput(f"meshtastic --configure example_config.yaml")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search('^Setting device owner to Bob TBeam', out, re.MULTILINE)
|
||||
assert re.search('^Fixing altitude at 304 meters', out, re.MULTILINE)
|
||||
assert re.search('^Fixing latitude at 35.8', out, re.MULTILINE)
|
||||
assert re.search('^Fixing longitude at -93.8', out, re.MULTILINE)
|
||||
assert re.search('^Setting device position', out, re.MULTILINE)
|
||||
assert re.search('^Set region to 1', out, re.MULTILINE)
|
||||
assert re.search('^Set is_always_powered to true', out, re.MULTILINE)
|
||||
assert re.search('^Set send_owner_interval to 2', out, re.MULTILINE)
|
||||
assert re.search('^Set screen_on_secs to 31536000', out, re.MULTILINE)
|
||||
assert re.search('^Set wait_bluetooth_secs to 31536000', out, re.MULTILINE)
|
||||
assert re.search('^Writing modified preferences to device', out, re.MULTILINE)
|
||||
|
||||
|
||||
@pytest.mark.smoke1
|
||||
def test_smoke1_factory_reset():
|
||||
"""Test factory reset"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set factory_reset true')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set factory_reset to true', out, re.MULTILINE)
|
||||
assert re.search(r'^Writing modified preferences to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# NOTE: The radio may not be responsive after this, may need to do a manual reboot
|
||||
# by pressing the button</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_ch_add_and_ch_del"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_ch_add_and_ch_del</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –ch-add</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_ch_add_and_ch_del():
|
||||
"""Test --ch-add"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-add testing')
|
||||
assert re.search(r'Writing modified channels to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'SECONDARY', out, re.MULTILINE)
|
||||
assert re.search(r'testing', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-index 1 --ch-del')
|
||||
assert re.search(r'Deleting channel 1', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
# make sure the secondar channel is not there
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert not re.search(r'SECONDARY', out, re.MULTILINE)
|
||||
assert not re.search(r'testing', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_ch_set_modem_config"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_ch_set_modem_config</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –ch-set modem_config</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_ch_set_modem_config():
|
||||
"""Test --ch-set modem_config"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config Bw31_25Cr48Sf512')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set modem_config to Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_ch_set_name"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_ch_set_name</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –ch-set name</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_ch_set_name():
|
||||
"""Test --ch-set name"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set name MyChannel')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set name to MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'MyChannel', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_ch_values"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_ch_values</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –ch-longslow, –ch-longfast, –ch-mediumslow, –ch-mediumsfast,
|
||||
–ch-shortslow, and –ch-shortfast arguments</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_ch_values():
|
||||
"""Test --ch-longslow, --ch-longfast, --ch-mediumslow, --ch-mediumsfast,
|
||||
--ch-shortslow, and --ch-shortfast arguments
|
||||
"""
|
||||
exp = {
|
||||
'--ch-longslow': 'Bw125Cr48Sf4096',
|
||||
# TODO: not sure why these fail thru tests, but ok manually
|
||||
#'--ch-longfast': 'Bw31_25Cr48Sf512',
|
||||
#'--ch-mediumslow': 'Bw250Cr46Sf2048',
|
||||
#'--ch-mediumfast': 'Bw250Cr47Sf1024',
|
||||
# TODO '--ch-shortslow': '?',
|
||||
'--ch-shortfast': 'Bw500Cr45Sf128'
|
||||
}
|
||||
|
||||
for key, val in exp.items():
|
||||
print(key, val)
|
||||
return_value, out = subprocess.getstatusoutput(f'meshtastic {key}')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'Writing modified channels to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio (might reboot)
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(val, out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_configure"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_configure</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –configure</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_configure():
|
||||
"""Test --configure"""
|
||||
_ , out = subprocess.getstatusoutput(f"meshtastic --configure example_config.yaml")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search('^Setting device owner to Bob TBeam', out, re.MULTILINE)
|
||||
assert re.search('^Fixing altitude at 304 meters', out, re.MULTILINE)
|
||||
assert re.search('^Fixing latitude at 35.8', out, re.MULTILINE)
|
||||
assert re.search('^Fixing longitude at -93.8', out, re.MULTILINE)
|
||||
assert re.search('^Setting device position', out, re.MULTILINE)
|
||||
assert re.search('^Set region to 1', out, re.MULTILINE)
|
||||
assert re.search('^Set is_always_powered to true', out, re.MULTILINE)
|
||||
assert re.search('^Set send_owner_interval to 2', out, re.MULTILINE)
|
||||
assert re.search('^Set screen_on_secs to 31536000', out, re.MULTILINE)
|
||||
assert re.search('^Set wait_bluetooth_secs to 31536000', out, re.MULTILINE)
|
||||
assert re.search('^Writing modified preferences to device', out, re.MULTILINE)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_debug"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_debug</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –debug</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_debug():
|
||||
"""Test --debug"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info --debug')
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^DEBUG:root', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_factory_reset"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_factory_reset</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test factory reset</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_factory_reset():
|
||||
"""Test factory reset"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set factory_reset true')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set factory_reset to true', out, re.MULTILINE)
|
||||
assert re.search(r'^Writing modified preferences to device', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# NOTE: The radio may not be responsive after this, may need to do a manual reboot
|
||||
# by pressing the button</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_info"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_info</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –info</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_info():
|
||||
"""Test --info"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^My info', out, re.MULTILINE)
|
||||
assert re.search(r'^Nodes in mesh', out, re.MULTILINE)
|
||||
assert re.search(r'^Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'^Channels', out, re.MULTILINE)
|
||||
assert re.search(r'^ PRIMARY', out, re.MULTILINE)
|
||||
assert re.search(r'^Primary channel URL', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_nodes"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_nodes</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –nodes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_nodes():
|
||||
"""Test --nodes"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --nodes')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^│ N │ User', out, re.MULTILINE)
|
||||
assert re.search(r'^│ 1 │', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_port"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_port</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –port</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_port():
|
||||
"""Test --port"""
|
||||
# first, get the ports
|
||||
ports = meshtastic.util.findPorts()
|
||||
# hopefully there is just one
|
||||
assert len(ports) == 1
|
||||
port = ports[0]
|
||||
return_value, out = subprocess.getstatusoutput(f'meshtastic --port {port} --info')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_qr"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_qr</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –qr</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_qr():
|
||||
"""Test --qr"""
|
||||
filename = 'tmpqr'
|
||||
if os.path.exists(f"{filename}"):
|
||||
os.remove(f"{filename}")
|
||||
return_value, _ = subprocess.getstatusoutput(f'meshtastic --qr > {filename}')
|
||||
assert os.path.exists(f"{filename}")
|
||||
# not really testing that a valid qr code is created, just that the file size
|
||||
# is reasonably big enough for a qr code
|
||||
assert os.stat(f"{filename}").st_size > 20000
|
||||
assert return_value == 0
|
||||
os.remove(f"{filename}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_reboot"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_reboot</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test reboot</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_reboot():
|
||||
"""Test reboot"""
|
||||
return_value, _ = subprocess.getstatusoutput('meshtastic --reboot')
|
||||
assert return_value == 0
|
||||
# pause for the radio to reset (10 seconds for the pause, and a few more seconds to be back up)
|
||||
time.sleep(18)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_send_hello"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_send_hello</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –sendtext hello</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_send_hello():
|
||||
"""Test --sendtext hello"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --sendtext hello')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Sending text message hello to \^all', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_seriallog_to_file"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_seriallog_to_file</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –seriallog to a file creates a file</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_seriallog_to_file():
|
||||
"""Test --seriallog to a file creates a file"""
|
||||
filename = 'tmpoutput.txt'
|
||||
if os.path.exists(f"{filename}"):
|
||||
os.remove(f"{filename}")
|
||||
return_value, _ = subprocess.getstatusoutput(f'meshtastic --info --seriallog {filename}')
|
||||
assert os.path.exists(f"{filename}")
|
||||
assert return_value == 0
|
||||
os.remove(f"{filename}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_set_is_router_false"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_set_is_router_false</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –set is_router false</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_set_is_router_false():
|
||||
"""Test --set is_router false"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router false')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set is_router to false', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
|
||||
assert re.search(r'^is_router: False', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_set_is_router_true"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_set_is_router_true</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –set is_router true</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_set_is_router_true():
|
||||
"""Test --set is_router true"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router true')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Set is_router to true', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
|
||||
assert re.search(r'^is_router: True', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_set_location_info"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_set_location_info</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –setlat, –setlon and –setalt</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_set_location_info():
|
||||
"""Test --setlat, --setlon and --setalt """
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --setlat 32.7767 --setlon -96.7970 --setalt 1337')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Fixing altitude', out, re.MULTILINE)
|
||||
assert re.search(r'^Fixing latitude', out, re.MULTILINE)
|
||||
assert re.search(r'^Fixing longitude', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out2 = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'1337', out2, re.MULTILINE)
|
||||
assert re.search(r'32.7767', out2, re.MULTILINE)
|
||||
assert re.search(r'-96.797', out2, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_set_owner"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_set_owner</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –set-owner name</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_set_owner():
|
||||
"""Test --set-owner name"""
|
||||
# make sure the owner is not Joe
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-owner Bob')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting device owner to Bob', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search(r'Owner: Joe', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-owner Joe')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting device owner to Joe', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Owner: Joe', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_set_team"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_set_team</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –set-team</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_set_team():
|
||||
"""Test --set-team """
|
||||
# unset the team
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CLEAR')
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search(r'^Setting team to CLEAR', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CYAN')
|
||||
assert re.search(r'Setting team to CYAN', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_REBOOT)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'CYAN', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_seturl_default"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_seturl_default</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –seturl with default value</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_seturl_default():
|
||||
"""Test --seturl with default value"""
|
||||
# set some channel value so we no longer have a default channel
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set name foo')
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
# ensure we no longer have a default primary channel
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert not re.search('CgUYAyIBAQ', out, re.MULTILINE)
|
||||
assert return_value == 0
|
||||
url = "https://www.meshtastic.org/d/#CgUYAyIBAQ"
|
||||
return_value, out = subprocess.getstatusoutput(f"meshtastic --seturl {url}")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert return_value == 0
|
||||
# pause for the radio
|
||||
time.sleep(PAUSE_AFTER_COMMAND)
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search('CgUYAyIBAQ', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_smoke1.test_smoke1_seturl_invalid_url"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke1_seturl_invalid_url</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –seturl with invalid url</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke1
|
||||
def test_smoke1_seturl_invalid_url():
|
||||
"""Test --seturl with invalid url"""
|
||||
# Note: This url is no longer a valid url.
|
||||
url = "https://www.meshtastic.org/c/#GAMiENTxuzogKQdZ8Lz_q89Oab8qB0RlZmF1bHQ="
|
||||
return_value, out = subprocess.getstatusoutput(f"meshtastic --seturl {url}")
|
||||
assert re.match(r'Connected to radio', out)
|
||||
assert re.search('Warning: There were no settings', out, re.MULTILINE)
|
||||
assert return_value == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.test" href="index.html">meshtastic.test</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_ch_add_and_ch_del" href="#meshtastic.test.test_smoke1.test_smoke1_ch_add_and_ch_del">test_smoke1_ch_add_and_ch_del</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_ch_set_modem_config" href="#meshtastic.test.test_smoke1.test_smoke1_ch_set_modem_config">test_smoke1_ch_set_modem_config</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_ch_set_name" href="#meshtastic.test.test_smoke1.test_smoke1_ch_set_name">test_smoke1_ch_set_name</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_ch_values" href="#meshtastic.test.test_smoke1.test_smoke1_ch_values">test_smoke1_ch_values</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_configure" href="#meshtastic.test.test_smoke1.test_smoke1_configure">test_smoke1_configure</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_debug" href="#meshtastic.test.test_smoke1.test_smoke1_debug">test_smoke1_debug</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_factory_reset" href="#meshtastic.test.test_smoke1.test_smoke1_factory_reset">test_smoke1_factory_reset</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_info" href="#meshtastic.test.test_smoke1.test_smoke1_info">test_smoke1_info</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_nodes" href="#meshtastic.test.test_smoke1.test_smoke1_nodes">test_smoke1_nodes</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_port" href="#meshtastic.test.test_smoke1.test_smoke1_port">test_smoke1_port</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_qr" href="#meshtastic.test.test_smoke1.test_smoke1_qr">test_smoke1_qr</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_reboot" href="#meshtastic.test.test_smoke1.test_smoke1_reboot">test_smoke1_reboot</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_send_hello" href="#meshtastic.test.test_smoke1.test_smoke1_send_hello">test_smoke1_send_hello</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_seriallog_to_file" href="#meshtastic.test.test_smoke1.test_smoke1_seriallog_to_file">test_smoke1_seriallog_to_file</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_set_is_router_false" href="#meshtastic.test.test_smoke1.test_smoke1_set_is_router_false">test_smoke1_set_is_router_false</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_set_is_router_true" href="#meshtastic.test.test_smoke1.test_smoke1_set_is_router_true">test_smoke1_set_is_router_true</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_set_location_info" href="#meshtastic.test.test_smoke1.test_smoke1_set_location_info">test_smoke1_set_location_info</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_set_owner" href="#meshtastic.test.test_smoke1.test_smoke1_set_owner">test_smoke1_set_owner</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_set_team" href="#meshtastic.test.test_smoke1.test_smoke1_set_team">test_smoke1_set_team</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_seturl_default" href="#meshtastic.test.test_smoke1.test_smoke1_seturl_default">test_smoke1_seturl_default</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_smoke1.test_smoke1_seturl_invalid_url" href="#meshtastic.test.test_smoke1.test_smoke1_seturl_invalid_url">test_smoke1_seturl_invalid_url</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,236 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.0" />
|
||||
<title>meshtastic.test.test_util API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for node.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.test.test_util</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for node.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for node.py"""
|
||||
|
||||
import pytest
|
||||
|
||||
from meshtastic.util import pskToString, our_exit
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_empty_string():
|
||||
"""Test pskToString empty string"""
|
||||
assert pskToString('') == 'unencrypted'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_string():
|
||||
"""Test pskToString string"""
|
||||
assert pskToString('hunter123') == 'secret'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_one_byte_zero_value():
|
||||
"""Test pskToString one byte that is value of 0"""
|
||||
assert pskToString(bytes([0x00])) == 'unencrypted'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_one_byte_non_zero_value():
|
||||
"""Test pskToString one byte that is non-zero"""
|
||||
assert pskToString(bytes([0x01])) == 'default'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_many_bytes():
|
||||
"""Test pskToString many bytes"""
|
||||
assert pskToString(bytes([0x02, 0x01])) == 'secret'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_our_exit_zero_return_value():
|
||||
"""Test our_exit with a zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Warning: Some message", 0)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 0
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_our_exit_non_zero_return_value():
|
||||
"""Test our_exit with a non-zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Error: Some message", 1)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.test.test_util.test_our_exit_non_zero_return_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_our_exit_non_zero_return_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test our_exit with a non-zero return value</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_our_exit_non_zero_return_value():
|
||||
"""Test our_exit with a non-zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Error: Some message", 1)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_our_exit_zero_return_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_our_exit_zero_return_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test our_exit with a zero return value</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_our_exit_zero_return_value():
|
||||
"""Test our_exit with a zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Warning: Some message", 0)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_pskToString_empty_string"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_empty_string</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString empty string</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_empty_string():
|
||||
"""Test pskToString empty string"""
|
||||
assert pskToString('') == 'unencrypted'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_pskToString_many_bytes"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_many_bytes</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString many bytes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_many_bytes():
|
||||
"""Test pskToString many bytes"""
|
||||
assert pskToString(bytes([0x02, 0x01])) == 'secret'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_pskToString_one_byte_non_zero_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_one_byte_non_zero_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString one byte that is non-zero</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_one_byte_non_zero_value():
|
||||
"""Test pskToString one byte that is non-zero"""
|
||||
assert pskToString(bytes([0x01])) == 'default'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_pskToString_one_byte_zero_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_one_byte_zero_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString one byte that is value of 0</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_one_byte_zero_value():
|
||||
"""Test pskToString one byte that is value of 0"""
|
||||
assert pskToString(bytes([0x00])) == 'unencrypted'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.test.test_util.test_pskToString_string"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_string</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString string</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_string():
|
||||
"""Test pskToString string"""
|
||||
assert pskToString('hunter123') == 'secret'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.test" href="index.html">meshtastic.test</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.test.test_util.test_our_exit_non_zero_return_value" href="#meshtastic.test.test_util.test_our_exit_non_zero_return_value">test_our_exit_non_zero_return_value</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_our_exit_zero_return_value" href="#meshtastic.test.test_util.test_our_exit_zero_return_value">test_our_exit_zero_return_value</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_pskToString_empty_string" href="#meshtastic.test.test_util.test_pskToString_empty_string">test_pskToString_empty_string</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_pskToString_many_bytes" href="#meshtastic.test.test_util.test_pskToString_many_bytes">test_pskToString_many_bytes</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_pskToString_one_byte_non_zero_value" href="#meshtastic.test.test_util.test_pskToString_one_byte_non_zero_value">test_pskToString_one_byte_non_zero_value</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_pskToString_one_byte_zero_value" href="#meshtastic.test.test_util.test_pskToString_one_byte_zero_value">test_pskToString_one_byte_zero_value</a></code></li>
|
||||
<li><code><a title="meshtastic.test.test_util.test_pskToString_string" href="#meshtastic.test.test_util.test_pskToString_string">test_pskToString_string</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,199 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.conftest API documentation</title>
|
||||
<meta name="description" content="Common pytest code (place for fixtures)." />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.conftest</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Common pytest code (place for fixtures).</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Common pytest code (place for fixtures)."""
|
||||
|
||||
import argparse
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
import pytest
|
||||
|
||||
from meshtastic.__main__ import Globals
|
||||
from ..mesh_interface import MeshInterface
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def reset_globals():
|
||||
"""Fixture to reset globals."""
|
||||
parser = None
|
||||
parser = argparse.ArgumentParser()
|
||||
Globals.getInstance().reset()
|
||||
Globals.getInstance().set_parser(parser)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def iface_with_nodes():
|
||||
"""Fixture to setup some nodes."""
|
||||
nodesById = {
|
||||
'!9388f81c': {
|
||||
'num': 2475227164,
|
||||
'user': {
|
||||
'id': '!9388f81c',
|
||||
'longName': 'Unknown f81c',
|
||||
'shortName': '?1C',
|
||||
'macaddr': 'RBeTiPgc',
|
||||
'hwModel': 'TBEAM'
|
||||
},
|
||||
'position': {},
|
||||
'lastHeard': 1640204888
|
||||
}
|
||||
}
|
||||
|
||||
nodesByNum = {
|
||||
2475227164: {
|
||||
'num': 2475227164,
|
||||
'user': {
|
||||
'id': '!9388f81c',
|
||||
'longName': 'Unknown f81c',
|
||||
'shortName': '?1C',
|
||||
'macaddr': 'RBeTiPgc',
|
||||
'hwModel': 'TBEAM'
|
||||
},
|
||||
'position': {
|
||||
'time': 1640206266
|
||||
},
|
||||
'lastHeard': 1640206266
|
||||
}
|
||||
}
|
||||
iface = MeshInterface(noProto=True)
|
||||
iface.nodes = nodesById
|
||||
iface.nodesByNum = nodesByNum
|
||||
myInfo = MagicMock()
|
||||
iface.myInfo = myInfo
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
return iface</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.conftest.iface_with_nodes"><code class="name flex">
|
||||
<span>def <span class="ident">iface_with_nodes</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Fixture to setup some nodes.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.fixture
|
||||
def iface_with_nodes():
|
||||
"""Fixture to setup some nodes."""
|
||||
nodesById = {
|
||||
'!9388f81c': {
|
||||
'num': 2475227164,
|
||||
'user': {
|
||||
'id': '!9388f81c',
|
||||
'longName': 'Unknown f81c',
|
||||
'shortName': '?1C',
|
||||
'macaddr': 'RBeTiPgc',
|
||||
'hwModel': 'TBEAM'
|
||||
},
|
||||
'position': {},
|
||||
'lastHeard': 1640204888
|
||||
}
|
||||
}
|
||||
|
||||
nodesByNum = {
|
||||
2475227164: {
|
||||
'num': 2475227164,
|
||||
'user': {
|
||||
'id': '!9388f81c',
|
||||
'longName': 'Unknown f81c',
|
||||
'shortName': '?1C',
|
||||
'macaddr': 'RBeTiPgc',
|
||||
'hwModel': 'TBEAM'
|
||||
},
|
||||
'position': {
|
||||
'time': 1640206266
|
||||
},
|
||||
'lastHeard': 1640206266
|
||||
}
|
||||
}
|
||||
iface = MeshInterface(noProto=True)
|
||||
iface.nodes = nodesById
|
||||
iface.nodesByNum = nodesByNum
|
||||
myInfo = MagicMock()
|
||||
iface.myInfo = myInfo
|
||||
iface.myInfo.my_node_num = 2475227164
|
||||
return iface</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.conftest.reset_globals"><code class="name flex">
|
||||
<span>def <span class="ident">reset_globals</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Fixture to reset globals.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.fixture
|
||||
def reset_globals():
|
||||
"""Fixture to reset globals."""
|
||||
parser = None
|
||||
parser = argparse.ArgumentParser()
|
||||
Globals.getInstance().reset()
|
||||
Globals.getInstance().set_parser(parser)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.conftest.iface_with_nodes" href="#meshtastic.tests.conftest.iface_with_nodes">iface_with_nodes</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.conftest.reset_globals" href="#meshtastic.tests.conftest.reset_globals">reset_globals</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,142 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests API documentation</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
||||
<dl>
|
||||
<dt><code class="name"><a title="meshtastic.tests.conftest" href="conftest.html">meshtastic.tests.conftest</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Common pytest code (place for fixtures).</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_ble_interface" href="test_ble_interface.html">meshtastic.tests.test_ble_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for ble_interface.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_examples" href="test_examples.html">meshtastic.tests.test_examples</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic test that the examples run as expected.
|
||||
We assume you have a python virtual environment in current directory.
|
||||
If not, you need to run: …</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_globals" href="test_globals.html">meshtastic.tests.test_globals</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for globals.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_int" href="test_int.html">meshtastic.tests.test_int</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic integration tests</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_main" href="test_main.html">meshtastic.tests.test_main</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for <strong>main</strong>.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_mesh_interface" href="test_mesh_interface.html">meshtastic.tests.test_mesh_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for mesh_interface.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_node" href="test_node.html">meshtastic.tests.test_node</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for node.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_remote_hardware" href="test_remote_hardware.html">meshtastic.tests.test_remote_hardware</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for remote_hardware.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_serial_interface" href="test_serial_interface.html">meshtastic.tests.test_serial_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for serial_interface.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_smoke1" href="test_smoke1.html">meshtastic.tests.test_smoke1</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic smoke tests with a single device via USB</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_smoke2" href="test_smoke2.html">meshtastic.tests.test_smoke2</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic smoke tests with 2 devices connected via USB</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_smoke_wifi" href="test_smoke_wifi.html">meshtastic.tests.test_smoke_wifi</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic smoke tests a device setup with wifi …</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_stream_interface" href="test_stream_interface.html">meshtastic.tests.test_stream_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for stream_interface.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_tcp_interface" href="test_tcp_interface.html">meshtastic.tests.test_tcp_interface</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for tcp_interface.py</p></div>
|
||||
</dd>
|
||||
<dt><code class="name"><a title="meshtastic.tests.test_util" href="test_util.html">meshtastic.tests.test_util</a></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Meshtastic unit tests for util.py</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="../index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests.conftest" href="conftest.html">meshtastic.tests.conftest</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_ble_interface" href="test_ble_interface.html">meshtastic.tests.test_ble_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_examples" href="test_examples.html">meshtastic.tests.test_examples</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_globals" href="test_globals.html">meshtastic.tests.test_globals</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_int" href="test_int.html">meshtastic.tests.test_int</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_main" href="test_main.html">meshtastic.tests.test_main</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_mesh_interface" href="test_mesh_interface.html">meshtastic.tests.test_mesh_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_node" href="test_node.html">meshtastic.tests.test_node</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware" href="test_remote_hardware.html">meshtastic.tests.test_remote_hardware</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_serial_interface" href="test_serial_interface.html">meshtastic.tests.test_serial_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_smoke1" href="test_smoke1.html">meshtastic.tests.test_smoke1</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_smoke2" href="test_smoke2.html">meshtastic.tests.test_smoke2</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_smoke_wifi" href="test_smoke_wifi.html">meshtastic.tests.test_smoke_wifi</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_stream_interface" href="test_stream_interface.html">meshtastic.tests.test_stream_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_tcp_interface" href="test_tcp_interface.html">meshtastic.tests.test_tcp_interface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util" href="test_util.html">meshtastic.tests.test_util</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,95 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_ble_interface API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for ble_interface.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_ble_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for ble_interface.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for ble_interface.py"""
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from ..ble_interface import BLEInterface
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_BLEInterface():
|
||||
"""Test that we can instantiate a BLEInterface"""
|
||||
iface = BLEInterface('foo', debugOut=True, noProto=True)
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_ble_interface.test_BLEInterface"><code class="name flex">
|
||||
<span>def <span class="ident">test_BLEInterface</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a BLEInterface</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_BLEInterface():
|
||||
"""Test that we can instantiate a BLEInterface"""
|
||||
iface = BLEInterface('foo', debugOut=True, noProto=True)
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_ble_interface.test_BLEInterface" href="#meshtastic.tests.test_ble_interface.test_BLEInterface">test_BLEInterface</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,132 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_examples API documentation</title>
|
||||
<meta name="description" content="Meshtastic test that the examples run as expected.
|
||||
We assume you have a python virtual environment in current directory.
|
||||
If not, you need to run: …" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_examples</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic test that the examples run as expected.
|
||||
We assume you have a python virtual environment in current directory.
|
||||
If not, you need to run: "python3 -m venv venv", "source venv/bin/activate", "pip install ."</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic test that the examples run as expected.
|
||||
We assume you have a python virtual environment in current directory.
|
||||
If not, you need to run: "python3 -m venv venv", "source venv/bin/activate", "pip install ."
|
||||
"""
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
@pytest.mark.examples
|
||||
def test_examples_hello_world_serial_no_arg():
|
||||
"""Test hello_world_serial without any args"""
|
||||
return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py')
|
||||
assert return_value == 3
|
||||
|
||||
|
||||
@pytest.mark.examples
|
||||
def test_examples_hello_world_serial_with_arg(capsys):
|
||||
"""Test hello_world_serial with arg"""
|
||||
return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py hello')
|
||||
assert return_value == 1
|
||||
_, err = capsys.readouterr()
|
||||
assert err == ''
|
||||
# TODO: Why does this not work?
|
||||
# assert out == 'Warning: No Meshtastic devices detected.'</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_examples.test_examples_hello_world_serial_no_arg"><code class="name flex">
|
||||
<span>def <span class="ident">test_examples_hello_world_serial_no_arg</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test hello_world_serial without any args</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.examples
|
||||
def test_examples_hello_world_serial_no_arg():
|
||||
"""Test hello_world_serial without any args"""
|
||||
return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py')
|
||||
assert return_value == 3</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_examples.test_examples_hello_world_serial_with_arg"><code class="name flex">
|
||||
<span>def <span class="ident">test_examples_hello_world_serial_with_arg</span></span>(<span>capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test hello_world_serial with arg</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.examples
|
||||
def test_examples_hello_world_serial_with_arg(capsys):
|
||||
"""Test hello_world_serial with arg"""
|
||||
return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py hello')
|
||||
assert return_value == 1
|
||||
_, err = capsys.readouterr()
|
||||
assert err == ''
|
||||
# TODO: Why does this not work?
|
||||
# assert out == 'Warning: No Meshtastic devices detected.'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_examples.test_examples_hello_world_serial_no_arg" href="#meshtastic.tests.test_examples.test_examples_hello_world_serial_no_arg">test_examples_hello_world_serial_no_arg</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_examples.test_examples_hello_world_serial_with_arg" href="#meshtastic.tests.test_examples.test_examples_hello_world_serial_with_arg">test_examples_hello_world_serial_with_arg</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,130 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_globals API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for globals.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_globals</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for globals.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""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</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_globals.test_globals_get_instaance"><code class="name flex">
|
||||
<span>def <span class="ident">test_globals_get_instaance</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a Globals instance</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@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</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_globals.test_globals_there_can_be_only_one"><code class="name flex">
|
||||
<span>def <span class="ident">test_globals_there_can_be_only_one</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can cannot create two Globals instances</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@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</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_globals.test_globals_get_instaance" href="#meshtastic.tests.test_globals.test_globals_get_instaance">test_globals_get_instaance</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_globals.test_globals_there_can_be_only_one" href="#meshtastic.tests.test_globals.test_globals_there_can_be_only_one">test_globals_there_can_be_only_one</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,177 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_int API documentation</title>
|
||||
<meta name="description" content="Meshtastic integration tests" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_int</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic integration tests</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic integration tests"""
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_no_args():
|
||||
"""Test without any args"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic')
|
||||
assert re.match(r'usage: meshtastic', out)
|
||||
assert return_value == 1
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_version():
|
||||
"""Test '--version'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --version')
|
||||
assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_help():
|
||||
"""Test '--help'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --help')
|
||||
assert re.match(r'usage: meshtastic ', out)
|
||||
assert return_value == 0
|
||||
|
||||
|
||||
@pytest.mark.int
|
||||
def test_int_support():
|
||||
"""Test '--support'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --support')
|
||||
assert re.search(r'System', out)
|
||||
assert re.search(r'Python', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_int.test_int_help"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_help</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–help'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_help():
|
||||
"""Test '--help'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --help')
|
||||
assert re.match(r'usage: meshtastic ', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_int.test_int_no_args"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_no_args</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test without any args</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_no_args():
|
||||
"""Test without any args"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic')
|
||||
assert re.match(r'usage: meshtastic', out)
|
||||
assert return_value == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_int.test_int_support"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_support</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–support'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_support():
|
||||
"""Test '--support'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --support')
|
||||
assert re.search(r'System', out)
|
||||
assert re.search(r'Python', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_int.test_int_version"><code class="name flex">
|
||||
<span>def <span class="ident">test_int_version</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test '–version'.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.int
|
||||
def test_int_version():
|
||||
"""Test '--version'."""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --version')
|
||||
assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_int.test_int_help" href="#meshtastic.tests.test_int.test_int_help">test_int_help</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_int.test_int_no_args" href="#meshtastic.tests.test_int.test_int_no_args">test_int_no_args</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_int.test_int_support" href="#meshtastic.tests.test_int.test_int_support">test_int_support</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_int.test_int_version" href="#meshtastic.tests.test_int.test_int_version">test_int_version</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,304 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_remote_hardware API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for remote_hardware.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_remote_hardware</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for remote_hardware.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for remote_hardware.py"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from unittest.mock import patch, MagicMock
|
||||
import pytest
|
||||
|
||||
from ..remote_hardware import RemoteHardwareClient, onGPIOreceive
|
||||
from ..serial_interface import SerialInterface
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_RemoteHardwareClient():
|
||||
"""Test that we can instantiate a RemoteHardwareClient instance"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
assert rhw.iface == iface
|
||||
iface.close()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_onGPIOreceive(capsys):
|
||||
"""Test onGPIOreceive"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
packet = {'decoded': {'remotehw': {'typ': 'foo', 'gpioValue': '4096' }}}
|
||||
onGPIOreceive(packet, iface)
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Received RemoteHardware', out)
|
||||
assert err == ''
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_RemoteHardwareClient_no_gpio_channel(capsys):
|
||||
"""Test that we can instantiate a RemoteHardwareClient instance but there is no channel named channel 'gpio'"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
|
||||
mo.localNode.getChannelByName.return_value = None
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
RemoteHardwareClient(mo)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: No channel named', out)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_readGPIOs(caplog):
|
||||
"""Test readGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.readGPIOs('0x10', 123)
|
||||
assert re.search(r'readGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_writeGPIOs(caplog):
|
||||
"""Test writeGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.writeGPIOs('0x10', 123, 1)
|
||||
assert re.search(r'writeGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_watchGPIOs(caplog):
|
||||
"""Test watchGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.watchGPIOs('0x10', 123)
|
||||
assert re.search(r'watchGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_sendHardware_no_nodeid():
|
||||
"""Test sending no nodeid to _sendHardware()"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
rhw = RemoteHardwareClient(mo)
|
||||
rhw._sendHardware(None, None)
|
||||
assert pytest_wrapped_e.type == SystemExit</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient"><code class="name flex">
|
||||
<span>def <span class="ident">test_RemoteHardwareClient</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a RemoteHardwareClient instance</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_RemoteHardwareClient():
|
||||
"""Test that we can instantiate a RemoteHardwareClient instance"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
assert rhw.iface == iface
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient_no_gpio_channel"><code class="name flex">
|
||||
<span>def <span class="ident">test_RemoteHardwareClient_no_gpio_channel</span></span>(<span>capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a RemoteHardwareClient instance but there is no channel named channel 'gpio'</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_RemoteHardwareClient_no_gpio_channel(capsys):
|
||||
"""Test that we can instantiate a RemoteHardwareClient instance but there is no channel named channel 'gpio'"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
|
||||
mo.localNode.getChannelByName.return_value = None
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
RemoteHardwareClient(mo)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: No channel named', out)
|
||||
assert err == ""</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_onGPIOreceive"><code class="name flex">
|
||||
<span>def <span class="ident">test_onGPIOreceive</span></span>(<span>capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test onGPIOreceive</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_onGPIOreceive(capsys):
|
||||
"""Test onGPIOreceive"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
packet = {'decoded': {'remotehw': {'typ': 'foo', 'gpioValue': '4096' }}}
|
||||
onGPIOreceive(packet, iface)
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Received RemoteHardware', out)
|
||||
assert err == ''</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_readGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">test_readGPIOs</span></span>(<span>caplog)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test readGPIOs</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_readGPIOs(caplog):
|
||||
"""Test readGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.readGPIOs('0x10', 123)
|
||||
assert re.search(r'readGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_sendHardware_no_nodeid"><code class="name flex">
|
||||
<span>def <span class="ident">test_sendHardware_no_nodeid</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test sending no nodeid to _sendHardware()</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_sendHardware_no_nodeid():
|
||||
"""Test sending no nodeid to _sendHardware()"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
rhw = RemoteHardwareClient(mo)
|
||||
rhw._sendHardware(None, None)
|
||||
assert pytest_wrapped_e.type == SystemExit</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_watchGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">test_watchGPIOs</span></span>(<span>caplog)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test watchGPIOs</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_watchGPIOs(caplog):
|
||||
"""Test watchGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.watchGPIOs('0x10', 123)
|
||||
assert re.search(r'watchGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_remote_hardware.test_writeGPIOs"><code class="name flex">
|
||||
<span>def <span class="ident">test_writeGPIOs</span></span>(<span>caplog)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test writeGPIOs</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_writeGPIOs(caplog):
|
||||
"""Test writeGPIOs"""
|
||||
iface = MagicMock(autospec=SerialInterface)
|
||||
rhw = RemoteHardwareClient(iface)
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
rhw.writeGPIOs('0x10', 123, 1)
|
||||
assert re.search(r'writeGPIOs', caplog.text, re.MULTILINE)
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient" href="#meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient">test_RemoteHardwareClient</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient_no_gpio_channel" href="#meshtastic.tests.test_remote_hardware.test_RemoteHardwareClient_no_gpio_channel">test_RemoteHardwareClient_no_gpio_channel</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_onGPIOreceive" href="#meshtastic.tests.test_remote_hardware.test_onGPIOreceive">test_onGPIOreceive</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_readGPIOs" href="#meshtastic.tests.test_remote_hardware.test_readGPIOs">test_readGPIOs</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_sendHardware_no_nodeid" href="#meshtastic.tests.test_remote_hardware.test_sendHardware_no_nodeid">test_sendHardware_no_nodeid</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_watchGPIOs" href="#meshtastic.tests.test_remote_hardware.test_watchGPIOs">test_watchGPIOs</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_remote_hardware.test_writeGPIOs" href="#meshtastic.tests.test_remote_hardware.test_writeGPIOs">test_writeGPIOs</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,186 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_serial_interface API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for serial_interface.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_serial_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for serial_interface.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for serial_interface.py"""
|
||||
|
||||
import re
|
||||
|
||||
|
||||
from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
from ..serial_interface import SerialInterface
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch('serial.Serial')
|
||||
@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake'])
|
||||
def test_SerialInterface_single_port(mocked_findPorts, mocked_serial):
|
||||
"""Test that we can instantiate a SerialInterface with a single port"""
|
||||
iface = SerialInterface(noProto=True)
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.close()
|
||||
mocked_findPorts.assert_called()
|
||||
mocked_serial.assert_called()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch('meshtastic.util.findPorts', return_value=[])
|
||||
def test_SerialInterface_no_ports(mocked_findPorts, capsys):
|
||||
"""Test that we can instantiate a SerialInterface with no ports"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
SerialInterface(noProto=True)
|
||||
mocked_findPorts.assert_called()
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: No Meshtastic devices detected', out, re.MULTILINE)
|
||||
assert err == ''
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake1', '/dev/ttyUSBfake2'])
|
||||
def test_SerialInterface_multiple_ports(mocked_findPorts, capsys):
|
||||
"""Test that we can instantiate a SerialInterface with two ports"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
SerialInterface(noProto=True)
|
||||
mocked_findPorts.assert_called()
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: Multiple serial ports were detected', out, re.MULTILINE)
|
||||
assert err == ''</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_serial_interface.test_SerialInterface_multiple_ports"><code class="name flex">
|
||||
<span>def <span class="ident">test_SerialInterface_multiple_ports</span></span>(<span>mocked_findPorts, capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a SerialInterface with two ports</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake1', '/dev/ttyUSBfake2'])
|
||||
def test_SerialInterface_multiple_ports(mocked_findPorts, capsys):
|
||||
"""Test that we can instantiate a SerialInterface with two ports"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
SerialInterface(noProto=True)
|
||||
mocked_findPorts.assert_called()
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: Multiple serial ports were detected', out, re.MULTILINE)
|
||||
assert err == ''</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_serial_interface.test_SerialInterface_no_ports"><code class="name flex">
|
||||
<span>def <span class="ident">test_SerialInterface_no_ports</span></span>(<span>mocked_findPorts, capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a SerialInterface with no ports</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
@patch('meshtastic.util.findPorts', return_value=[])
|
||||
def test_SerialInterface_no_ports(mocked_findPorts, capsys):
|
||||
"""Test that we can instantiate a SerialInterface with no ports"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
SerialInterface(noProto=True)
|
||||
mocked_findPorts.assert_called()
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Warning: No Meshtastic devices detected', out, re.MULTILINE)
|
||||
assert err == ''</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_serial_interface.test_SerialInterface_single_port"><code class="name flex">
|
||||
<span>def <span class="ident">test_SerialInterface_single_port</span></span>(<span>mocked_findPorts, mocked_serial)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a SerialInterface with a single port</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
@patch('serial.Serial')
|
||||
@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake'])
|
||||
def test_SerialInterface_single_port(mocked_findPorts, mocked_serial):
|
||||
"""Test that we can instantiate a SerialInterface with a single port"""
|
||||
iface = SerialInterface(noProto=True)
|
||||
iface.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
iface.close()
|
||||
mocked_findPorts.assert_called()
|
||||
mocked_serial.assert_called()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_serial_interface.test_SerialInterface_multiple_ports" href="#meshtastic.tests.test_serial_interface.test_SerialInterface_multiple_ports">test_SerialInterface_multiple_ports</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_serial_interface.test_SerialInterface_no_ports" href="#meshtastic.tests.test_serial_interface.test_SerialInterface_no_ports">test_SerialInterface_no_ports</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_serial_interface.test_SerialInterface_single_port" href="#meshtastic.tests.test_serial_interface.test_SerialInterface_single_port">test_SerialInterface_single_port</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,127 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_smoke2 API documentation</title>
|
||||
<meta name="description" content="Meshtastic smoke tests with 2 devices connected via USB" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_smoke2</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic smoke tests with 2 devices connected via USB</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic smoke tests with 2 devices connected via USB"""
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.smoke2
|
||||
def test_smoke2_info():
|
||||
"""Test --info with 2 devices connected serially"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Warning: Multiple', out, re.MULTILINE)
|
||||
assert return_value == 1
|
||||
|
||||
|
||||
@pytest.mark.smoke2
|
||||
def test_smoke2_test():
|
||||
"""Test --test"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --test')
|
||||
assert re.search(r'Writing serial debugging', out, re.MULTILINE)
|
||||
assert re.search(r'Ports opened', out, re.MULTILINE)
|
||||
assert re.search(r'Running 5 tests', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_smoke2.test_smoke2_info"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke2_info</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –info with 2 devices connected serially</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke2
|
||||
def test_smoke2_info():
|
||||
"""Test --info with 2 devices connected serially"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info')
|
||||
assert re.search(r'Warning: Multiple', out, re.MULTILINE)
|
||||
assert return_value == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_smoke2.test_smoke2_test"><code class="name flex">
|
||||
<span>def <span class="ident">test_smoke2_test</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –test</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smoke2
|
||||
def test_smoke2_test():
|
||||
"""Test --test"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --test')
|
||||
assert re.search(r'Writing serial debugging', out, re.MULTILINE)
|
||||
assert re.search(r'Ports opened', out, re.MULTILINE)
|
||||
assert re.search(r'Running 5 tests', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_smoke2.test_smoke2_info" href="#meshtastic.tests.test_smoke2.test_smoke2_info">test_smoke2_info</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_smoke2.test_smoke2_test" href="#meshtastic.tests.test_smoke2.test_smoke2_test">test_smoke2_test</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,115 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_smoke_wifi API documentation</title>
|
||||
<meta name="description" content="Meshtastic smoke tests a device setup with wifi …" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_smoke_wifi</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic smoke tests a device setup with wifi.</p>
|
||||
<p>Need to have run the following on an esp32 device:
|
||||
meshtastic –set wifi_ssid 'foo' –set wifi_password 'sekret'</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic smoke tests a device setup with wifi.
|
||||
|
||||
Need to have run the following on an esp32 device:
|
||||
meshtastic --set wifi_ssid 'foo' --set wifi_password 'sekret'
|
||||
"""
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.smokewifi
|
||||
def test_smokewifi_info():
|
||||
"""Test --info"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info --host meshtastic.local')
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^My info', out, re.MULTILINE)
|
||||
assert re.search(r'^Nodes in mesh', out, re.MULTILINE)
|
||||
assert re.search(r'^Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'^Channels', out, re.MULTILINE)
|
||||
assert re.search(r'^ PRIMARY', out, re.MULTILINE)
|
||||
assert re.search(r'^Primary channel URL', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_smoke_wifi.test_smokewifi_info"><code class="name flex">
|
||||
<span>def <span class="ident">test_smokewifi_info</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test –info</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.smokewifi
|
||||
def test_smokewifi_info():
|
||||
"""Test --info"""
|
||||
return_value, out = subprocess.getstatusoutput('meshtastic --info --host meshtastic.local')
|
||||
assert re.search(r'^Owner', out, re.MULTILINE)
|
||||
assert re.search(r'^My info', out, re.MULTILINE)
|
||||
assert re.search(r'^Nodes in mesh', out, re.MULTILINE)
|
||||
assert re.search(r'^Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'^Channels', out, re.MULTILINE)
|
||||
assert re.search(r'^ PRIMARY', out, re.MULTILINE)
|
||||
assert re.search(r'^Primary channel URL', out, re.MULTILINE)
|
||||
assert return_value == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_smoke_wifi.test_smokewifi_info" href="#meshtastic.tests.test_smoke_wifi.test_smokewifi_info">test_smokewifi_info</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,246 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_stream_interface API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for stream_interface.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_stream_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for stream_interface.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for stream_interface.py"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
import pytest
|
||||
|
||||
from ..stream_interface import StreamInterface
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_StreamInterface():
|
||||
"""Test that we cannot instantiate a StreamInterface based on noProto"""
|
||||
with pytest.raises(Exception) as pytest_wrapped_e:
|
||||
StreamInterface()
|
||||
assert pytest_wrapped_e.type == Exception
|
||||
|
||||
|
||||
# Note: This takes a bit, so moving from unit to slow
|
||||
@pytest.mark.unitslow
|
||||
def test_StreamInterface_with_noProto(caplog, reset_globals):
|
||||
"""Test that we can instantiate a StreamInterface based on nonProto
|
||||
and we can read/write bytes from a mocked stream
|
||||
"""
|
||||
stream = MagicMock()
|
||||
test_data = b'hello'
|
||||
stream.read.return_value = test_data
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
iface = StreamInterface(noProto=True, connectNow=False)
|
||||
iface.stream = stream
|
||||
iface._writeBytes(test_data)
|
||||
data = iface._readBytes(len(test_data))
|
||||
assert data == test_data
|
||||
|
||||
|
||||
# Note: This takes a bit, so moving from unit to slow
|
||||
# Tip: If you want to see the print output, run with '-s' flag:
|
||||
# pytest -s meshtastic/tests/test_stream_interface.py::test_sendToRadioImpl
|
||||
@pytest.mark.unitslow
|
||||
def test_sendToRadioImpl(caplog, reset_globals):
|
||||
"""Test _sendToRadioImpl()"""
|
||||
|
||||
# def add_header(b):
|
||||
# """Add header stuffs for radio"""
|
||||
# bufLen = len(b)
|
||||
# header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
|
||||
# return header + b
|
||||
|
||||
# captured raw bytes of a Heltec2.1 radio with 2 channels (primary and a secondary channel named "gpio")
|
||||
raw_1_my_info = b'\x1a,\x08\xdc\x8c\xd5\xc5\x02\x18\r2\x0e1.2.49.5354c49P\x15]\xe1%\x17Eh\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
|
||||
raw_2_node_info = b'"9\x08\xdc\x8c\xd5\xc5\x02\x12(\n\t!28b5465c\x12\x0cUnknown 465c\x1a\x03?5C"\x06$o(\xb5F\\0\n\x1a\x02 1%M<\xc6a'
|
||||
# pylint: disable=C0301
|
||||
raw_3_node_info = b'"C\x08\xa4\x8c\xd5\xc5\x02\x12(\n\t!28b54624\x12\x0cUnknown 4624\x1a\x03?24"\x06$o(\xb5F$0\n\x1a\x07 5MH<\xc6a%G<\xc6a=\x00\x00\xc0@'
|
||||
raw_4_complete = b'@\xcf\xe5\xd1\x8c\x0e'
|
||||
# pylint: disable=C0301
|
||||
raw_5_prefs = b'Z6\r\\F\xb5(\x15\\F\xb5("\x1c\x08\x06\x12\x13*\x11\n\x0f0\x84\x07P\xac\x02\x88\x01\x01\xb0\t#\xb8\t\x015]$\xddk5\xd5\x7f!b=M<\xc6aP\x03`F'
|
||||
# pylint: disable=C0301
|
||||
raw_6_channel0 = b'Z.\r\\F\xb5(\x15\\F\xb5("\x14\x08\x06\x12\x0b:\t\x12\x05\x18\x01"\x01\x01\x18\x015^$\xddk5\xd6\x7f!b=M<\xc6aP\x03`F'
|
||||
# pylint: disable=C0301
|
||||
raw_7_channel1 = b'ZS\r\\F\xb5(\x15\\F\xb5("9\x08\x06\x120:.\x08\x01\x12(" \xb4&\xb3\xc7\x06\xd8\xe39%\xba\xa5\xee\x8eH\x06\xf6\xf4H\xe8\xd5\xc1[ao\xb5Y\\\xb4"\xafmi*\x04gpio\x18\x025_$\xddk5\xd7\x7f!b=M<\xc6aP\x03`F'
|
||||
raw_8_channel2 = b'Z)\r\\F\xb5(\x15\\F\xb5("\x0f\x08\x06\x12\x06:\x04\x08\x02\x12\x005`$\xddk5\xd8\x7f!b=M<\xc6aP\x03`F'
|
||||
raw_blank = b''
|
||||
|
||||
test_data = b'hello'
|
||||
stream = MagicMock()
|
||||
#stream.read.return_value = add_header(test_data)
|
||||
stream.read.side_effect = [ raw_1_my_info, raw_2_node_info, raw_3_node_info, raw_4_complete,
|
||||
raw_5_prefs, raw_6_channel0, raw_7_channel1, raw_8_channel2,
|
||||
raw_blank, raw_blank]
|
||||
toRadio = MagicMock()
|
||||
toRadio.SerializeToString.return_value = test_data
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
iface = StreamInterface(noProto=True, connectNow=False)
|
||||
iface.stream = stream
|
||||
iface.connect()
|
||||
iface._sendToRadioImpl(toRadio)
|
||||
assert re.search(r'Sending: ', caplog.text, re.MULTILINE)
|
||||
assert re.search(r'reading character', caplog.text, re.MULTILINE)
|
||||
assert re.search(r'In reader loop', caplog.text, re.MULTILINE)
|
||||
print(caplog.text)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_stream_interface.test_StreamInterface"><code class="name flex">
|
||||
<span>def <span class="ident">test_StreamInterface</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we cannot instantiate a StreamInterface based on noProto</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_StreamInterface():
|
||||
"""Test that we cannot instantiate a StreamInterface based on noProto"""
|
||||
with pytest.raises(Exception) as pytest_wrapped_e:
|
||||
StreamInterface()
|
||||
assert pytest_wrapped_e.type == Exception</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_stream_interface.test_StreamInterface_with_noProto"><code class="name flex">
|
||||
<span>def <span class="ident">test_StreamInterface_with_noProto</span></span>(<span>caplog, reset_globals)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a StreamInterface based on nonProto
|
||||
and we can read/write bytes from a mocked stream</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unitslow
|
||||
def test_StreamInterface_with_noProto(caplog, reset_globals):
|
||||
"""Test that we can instantiate a StreamInterface based on nonProto
|
||||
and we can read/write bytes from a mocked stream
|
||||
"""
|
||||
stream = MagicMock()
|
||||
test_data = b'hello'
|
||||
stream.read.return_value = test_data
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
iface = StreamInterface(noProto=True, connectNow=False)
|
||||
iface.stream = stream
|
||||
iface._writeBytes(test_data)
|
||||
data = iface._readBytes(len(test_data))
|
||||
assert data == test_data</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_stream_interface.test_sendToRadioImpl"><code class="name flex">
|
||||
<span>def <span class="ident">test_sendToRadioImpl</span></span>(<span>caplog, reset_globals)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test _sendToRadioImpl()</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unitslow
|
||||
def test_sendToRadioImpl(caplog, reset_globals):
|
||||
"""Test _sendToRadioImpl()"""
|
||||
|
||||
# def add_header(b):
|
||||
# """Add header stuffs for radio"""
|
||||
# bufLen = len(b)
|
||||
# header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
|
||||
# return header + b
|
||||
|
||||
# captured raw bytes of a Heltec2.1 radio with 2 channels (primary and a secondary channel named "gpio")
|
||||
raw_1_my_info = b'\x1a,\x08\xdc\x8c\xd5\xc5\x02\x18\r2\x0e1.2.49.5354c49P\x15]\xe1%\x17Eh\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
|
||||
raw_2_node_info = b'"9\x08\xdc\x8c\xd5\xc5\x02\x12(\n\t!28b5465c\x12\x0cUnknown 465c\x1a\x03?5C"\x06$o(\xb5F\\0\n\x1a\x02 1%M<\xc6a'
|
||||
# pylint: disable=C0301
|
||||
raw_3_node_info = b'"C\x08\xa4\x8c\xd5\xc5\x02\x12(\n\t!28b54624\x12\x0cUnknown 4624\x1a\x03?24"\x06$o(\xb5F$0\n\x1a\x07 5MH<\xc6a%G<\xc6a=\x00\x00\xc0@'
|
||||
raw_4_complete = b'@\xcf\xe5\xd1\x8c\x0e'
|
||||
# pylint: disable=C0301
|
||||
raw_5_prefs = b'Z6\r\\F\xb5(\x15\\F\xb5("\x1c\x08\x06\x12\x13*\x11\n\x0f0\x84\x07P\xac\x02\x88\x01\x01\xb0\t#\xb8\t\x015]$\xddk5\xd5\x7f!b=M<\xc6aP\x03`F'
|
||||
# pylint: disable=C0301
|
||||
raw_6_channel0 = b'Z.\r\\F\xb5(\x15\\F\xb5("\x14\x08\x06\x12\x0b:\t\x12\x05\x18\x01"\x01\x01\x18\x015^$\xddk5\xd6\x7f!b=M<\xc6aP\x03`F'
|
||||
# pylint: disable=C0301
|
||||
raw_7_channel1 = b'ZS\r\\F\xb5(\x15\\F\xb5("9\x08\x06\x120:.\x08\x01\x12(" \xb4&\xb3\xc7\x06\xd8\xe39%\xba\xa5\xee\x8eH\x06\xf6\xf4H\xe8\xd5\xc1[ao\xb5Y\\\xb4"\xafmi*\x04gpio\x18\x025_$\xddk5\xd7\x7f!b=M<\xc6aP\x03`F'
|
||||
raw_8_channel2 = b'Z)\r\\F\xb5(\x15\\F\xb5("\x0f\x08\x06\x12\x06:\x04\x08\x02\x12\x005`$\xddk5\xd8\x7f!b=M<\xc6aP\x03`F'
|
||||
raw_blank = b''
|
||||
|
||||
test_data = b'hello'
|
||||
stream = MagicMock()
|
||||
#stream.read.return_value = add_header(test_data)
|
||||
stream.read.side_effect = [ raw_1_my_info, raw_2_node_info, raw_3_node_info, raw_4_complete,
|
||||
raw_5_prefs, raw_6_channel0, raw_7_channel1, raw_8_channel2,
|
||||
raw_blank, raw_blank]
|
||||
toRadio = MagicMock()
|
||||
toRadio.SerializeToString.return_value = test_data
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
iface = StreamInterface(noProto=True, connectNow=False)
|
||||
iface.stream = stream
|
||||
iface.connect()
|
||||
iface._sendToRadioImpl(toRadio)
|
||||
assert re.search(r'Sending: ', caplog.text, re.MULTILINE)
|
||||
assert re.search(r'reading character', caplog.text, re.MULTILINE)
|
||||
assert re.search(r'In reader loop', caplog.text, re.MULTILINE)
|
||||
print(caplog.text)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_stream_interface.test_StreamInterface" href="#meshtastic.tests.test_stream_interface.test_StreamInterface">test_StreamInterface</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_stream_interface.test_StreamInterface_with_noProto" href="#meshtastic.tests.test_stream_interface.test_StreamInterface_with_noProto">test_StreamInterface_with_noProto</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_stream_interface.test_sendToRadioImpl" href="#meshtastic.tests.test_stream_interface.test_sendToRadioImpl">test_sendToRadioImpl</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,120 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_tcp_interface API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for tcp_interface.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_tcp_interface</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for tcp_interface.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for tcp_interface.py"""
|
||||
|
||||
import re
|
||||
|
||||
from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
from ..tcp_interface import TCPInterface
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
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.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Owner: None \(None\)', out, re.MULTILINE)
|
||||
assert re.search(r'Nodes', out, re.MULTILINE)
|
||||
assert re.search(r'Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'Channels', out, re.MULTILINE)
|
||||
assert re.search(r'Primary channel URL', out, re.MULTILINE)
|
||||
assert err == ''
|
||||
assert mock_socket.called
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_tcp_interface.test_TCPInterface"><code class="name flex">
|
||||
<span>def <span class="ident">test_TCPInterface</span></span>(<span>capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test that we can instantiate a TCPInterface</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
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.showInfo()
|
||||
iface.localNode.showInfo()
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'Owner: None \(None\)', out, re.MULTILINE)
|
||||
assert re.search(r'Nodes', out, re.MULTILINE)
|
||||
assert re.search(r'Preferences', out, re.MULTILINE)
|
||||
assert re.search(r'Channels', out, re.MULTILINE)
|
||||
assert re.search(r'Primary channel URL', out, re.MULTILINE)
|
||||
assert err == ''
|
||||
assert mock_socket.called
|
||||
iface.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_tcp_interface.test_TCPInterface" href="#meshtastic.tests.test_tcp_interface.test_TCPInterface">test_TCPInterface</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,519 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tests.test_util API documentation</title>
|
||||
<meta name="description" content="Meshtastic unit tests for util.py" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tests.test_util</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Meshtastic unit tests for util.py</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Meshtastic unit tests for util.py"""
|
||||
|
||||
import re
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from meshtastic.util import (fixme, stripnl, pskToString, our_exit,
|
||||
support_info, genPSK256, fromStr, fromPSK,
|
||||
quoteBooleans, catchAndIgnore)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_genPSK256():
|
||||
"""Test genPSK256"""
|
||||
assert genPSK256() != ''
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_fromStr():
|
||||
"""Test fromStr"""
|
||||
assert fromStr('') == b''
|
||||
assert fromStr('0x12') == b'\x12'
|
||||
assert fromStr('t')
|
||||
assert fromStr('T')
|
||||
assert fromStr('true')
|
||||
assert fromStr('True')
|
||||
assert fromStr('yes')
|
||||
assert fromStr('Yes')
|
||||
assert fromStr('f') is False
|
||||
assert fromStr('F') is False
|
||||
assert fromStr('false') is False
|
||||
assert fromStr('False') is False
|
||||
assert fromStr('no') is False
|
||||
assert fromStr('No') is False
|
||||
assert fromStr('100.01') == 100.01
|
||||
assert fromStr('123') == 123
|
||||
assert fromStr('abc') == 'abc'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_quoteBooleans():
|
||||
"""Test quoteBooleans"""
|
||||
assert quoteBooleans('') == ''
|
||||
assert quoteBooleans('foo') == 'foo'
|
||||
assert quoteBooleans('true') == 'true'
|
||||
assert quoteBooleans('false') == 'false'
|
||||
assert quoteBooleans(': true') == ": 'true'"
|
||||
assert quoteBooleans(': false') == ": 'false'"
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_fromPSK():
|
||||
"""Test fromPSK"""
|
||||
assert fromPSK('random') != ''
|
||||
assert fromPSK('none') == b'\x00'
|
||||
assert fromPSK('default') == b'\x01'
|
||||
assert fromPSK('simple22') == b'\x17'
|
||||
assert fromPSK('trash') == 'trash'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_stripnl():
|
||||
"""Test stripnl"""
|
||||
assert stripnl('') == ''
|
||||
assert stripnl('a\n') == 'a'
|
||||
assert stripnl(' a \n ') == 'a'
|
||||
assert stripnl('a\nb') == 'a b'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_empty_string():
|
||||
"""Test pskToString empty string"""
|
||||
assert pskToString('') == 'unencrypted'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_string():
|
||||
"""Test pskToString string"""
|
||||
assert pskToString('hunter123') == 'secret'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_one_byte_zero_value():
|
||||
"""Test pskToString one byte that is value of 0"""
|
||||
assert pskToString(bytes([0x00])) == 'unencrypted'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_one_byte_non_zero_value():
|
||||
"""Test pskToString one byte that is non-zero"""
|
||||
assert pskToString(bytes([0x01])) == 'default'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_many_bytes():
|
||||
"""Test pskToString many bytes"""
|
||||
assert pskToString(bytes([0x02, 0x01])) == 'secret'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_pskToString_simple():
|
||||
"""Test pskToString simple"""
|
||||
assert pskToString(bytes([0x03])) == 'simple2'
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_our_exit_zero_return_value():
|
||||
"""Test our_exit with a zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Warning: Some message", 0)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 0
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_our_exit_non_zero_return_value():
|
||||
"""Test our_exit with a non-zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Error: Some message", 1)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_fixme():
|
||||
"""Test fixme()"""
|
||||
with pytest.raises(Exception) as pytest_wrapped_e:
|
||||
fixme("some exception")
|
||||
assert pytest_wrapped_e.type == Exception
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_support_info(capsys):
|
||||
"""Test support_info"""
|
||||
support_info()
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'System', out, re.MULTILINE)
|
||||
assert re.search(r'Platform', out, re.MULTILINE)
|
||||
assert re.search(r'Machine', out, re.MULTILINE)
|
||||
assert re.search(r'Executable', out, re.MULTILINE)
|
||||
assert err == ''
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_catchAndIgnore(caplog):
|
||||
"""Test catchAndIgnore() does not actually throw an exception, but just logs"""
|
||||
def some_closure():
|
||||
raise Exception('foo')
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
catchAndIgnore("something", some_closure)
|
||||
assert re.search(r'Exception thrown in something', caplog.text, re.MULTILINE)</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tests.test_util.test_catchAndIgnore"><code class="name flex">
|
||||
<span>def <span class="ident">test_catchAndIgnore</span></span>(<span>caplog)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test catchAndIgnore() does not actually throw an exception, but just logs</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_catchAndIgnore(caplog):
|
||||
"""Test catchAndIgnore() does not actually throw an exception, but just logs"""
|
||||
def some_closure():
|
||||
raise Exception('foo')
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
catchAndIgnore("something", some_closure)
|
||||
assert re.search(r'Exception thrown in something', caplog.text, re.MULTILINE)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_fixme"><code class="name flex">
|
||||
<span>def <span class="ident">test_fixme</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test fixme()</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_fixme():
|
||||
"""Test fixme()"""
|
||||
with pytest.raises(Exception) as pytest_wrapped_e:
|
||||
fixme("some exception")
|
||||
assert pytest_wrapped_e.type == Exception</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_fromPSK"><code class="name flex">
|
||||
<span>def <span class="ident">test_fromPSK</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test fromPSK</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_fromPSK():
|
||||
"""Test fromPSK"""
|
||||
assert fromPSK('random') != ''
|
||||
assert fromPSK('none') == b'\x00'
|
||||
assert fromPSK('default') == b'\x01'
|
||||
assert fromPSK('simple22') == b'\x17'
|
||||
assert fromPSK('trash') == 'trash'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_fromStr"><code class="name flex">
|
||||
<span>def <span class="ident">test_fromStr</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test fromStr</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_fromStr():
|
||||
"""Test fromStr"""
|
||||
assert fromStr('') == b''
|
||||
assert fromStr('0x12') == b'\x12'
|
||||
assert fromStr('t')
|
||||
assert fromStr('T')
|
||||
assert fromStr('true')
|
||||
assert fromStr('True')
|
||||
assert fromStr('yes')
|
||||
assert fromStr('Yes')
|
||||
assert fromStr('f') is False
|
||||
assert fromStr('F') is False
|
||||
assert fromStr('false') is False
|
||||
assert fromStr('False') is False
|
||||
assert fromStr('no') is False
|
||||
assert fromStr('No') is False
|
||||
assert fromStr('100.01') == 100.01
|
||||
assert fromStr('123') == 123
|
||||
assert fromStr('abc') == 'abc'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_genPSK256"><code class="name flex">
|
||||
<span>def <span class="ident">test_genPSK256</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test genPSK256</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_genPSK256():
|
||||
"""Test genPSK256"""
|
||||
assert genPSK256() != ''</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_our_exit_non_zero_return_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_our_exit_non_zero_return_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test our_exit with a non-zero return value</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_our_exit_non_zero_return_value():
|
||||
"""Test our_exit with a non-zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Error: Some message", 1)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 1</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_our_exit_zero_return_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_our_exit_zero_return_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test our_exit with a zero return value</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_our_exit_zero_return_value():
|
||||
"""Test our_exit with a zero return value"""
|
||||
with pytest.raises(SystemExit) as pytest_wrapped_e:
|
||||
our_exit("Warning: Some message", 0)
|
||||
assert pytest_wrapped_e.type == SystemExit
|
||||
assert pytest_wrapped_e.value.code == 0</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_empty_string"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_empty_string</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString empty string</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_empty_string():
|
||||
"""Test pskToString empty string"""
|
||||
assert pskToString('') == 'unencrypted'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_many_bytes"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_many_bytes</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString many bytes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_many_bytes():
|
||||
"""Test pskToString many bytes"""
|
||||
assert pskToString(bytes([0x02, 0x01])) == 'secret'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_one_byte_non_zero_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_one_byte_non_zero_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString one byte that is non-zero</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_one_byte_non_zero_value():
|
||||
"""Test pskToString one byte that is non-zero"""
|
||||
assert pskToString(bytes([0x01])) == 'default'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_one_byte_zero_value"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_one_byte_zero_value</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString one byte that is value of 0</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_one_byte_zero_value():
|
||||
"""Test pskToString one byte that is value of 0"""
|
||||
assert pskToString(bytes([0x00])) == 'unencrypted'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_simple"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_simple</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString simple</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_simple():
|
||||
"""Test pskToString simple"""
|
||||
assert pskToString(bytes([0x03])) == 'simple2'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_pskToString_string"><code class="name flex">
|
||||
<span>def <span class="ident">test_pskToString_string</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test pskToString string</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_pskToString_string():
|
||||
"""Test pskToString string"""
|
||||
assert pskToString('hunter123') == 'secret'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_quoteBooleans"><code class="name flex">
|
||||
<span>def <span class="ident">test_quoteBooleans</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test quoteBooleans</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_quoteBooleans():
|
||||
"""Test quoteBooleans"""
|
||||
assert quoteBooleans('') == ''
|
||||
assert quoteBooleans('foo') == 'foo'
|
||||
assert quoteBooleans('true') == 'true'
|
||||
assert quoteBooleans('false') == 'false'
|
||||
assert quoteBooleans(': true') == ": 'true'"
|
||||
assert quoteBooleans(': false') == ": 'false'"</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_stripnl"><code class="name flex">
|
||||
<span>def <span class="ident">test_stripnl</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test stripnl</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_stripnl():
|
||||
"""Test stripnl"""
|
||||
assert stripnl('') == ''
|
||||
assert stripnl('a\n') == 'a'
|
||||
assert stripnl(' a \n ') == 'a'
|
||||
assert stripnl('a\nb') == 'a b'</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tests.test_util.test_support_info"><code class="name flex">
|
||||
<span>def <span class="ident">test_support_info</span></span>(<span>capsys)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Test support_info</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">@pytest.mark.unit
|
||||
def test_support_info(capsys):
|
||||
"""Test support_info"""
|
||||
support_info()
|
||||
out, err = capsys.readouterr()
|
||||
assert re.search(r'System', out, re.MULTILINE)
|
||||
assert re.search(r'Platform', out, re.MULTILINE)
|
||||
assert re.search(r'Machine', out, re.MULTILINE)
|
||||
assert re.search(r'Executable', out, re.MULTILINE)
|
||||
assert err == ''</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic.tests" href="index.html">meshtastic.tests</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tests.test_util.test_catchAndIgnore" href="#meshtastic.tests.test_util.test_catchAndIgnore">test_catchAndIgnore</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_fixme" href="#meshtastic.tests.test_util.test_fixme">test_fixme</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_fromPSK" href="#meshtastic.tests.test_util.test_fromPSK">test_fromPSK</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_fromStr" href="#meshtastic.tests.test_util.test_fromStr">test_fromStr</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_genPSK256" href="#meshtastic.tests.test_util.test_genPSK256">test_genPSK256</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_our_exit_non_zero_return_value" href="#meshtastic.tests.test_util.test_our_exit_non_zero_return_value">test_our_exit_non_zero_return_value</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_our_exit_zero_return_value" href="#meshtastic.tests.test_util.test_our_exit_zero_return_value">test_our_exit_zero_return_value</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_empty_string" href="#meshtastic.tests.test_util.test_pskToString_empty_string">test_pskToString_empty_string</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_many_bytes" href="#meshtastic.tests.test_util.test_pskToString_many_bytes">test_pskToString_many_bytes</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_one_byte_non_zero_value" href="#meshtastic.tests.test_util.test_pskToString_one_byte_non_zero_value">test_pskToString_one_byte_non_zero_value</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_one_byte_zero_value" href="#meshtastic.tests.test_util.test_pskToString_one_byte_zero_value">test_pskToString_one_byte_zero_value</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_simple" href="#meshtastic.tests.test_util.test_pskToString_simple">test_pskToString_simple</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_pskToString_string" href="#meshtastic.tests.test_util.test_pskToString_string">test_pskToString_string</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_quoteBooleans" href="#meshtastic.tests.test_util.test_quoteBooleans">test_quoteBooleans</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_stripnl" href="#meshtastic.tests.test_util.test_stripnl">test_stripnl</a></code></li>
|
||||
<li><code><a title="meshtastic.tests.test_util.test_support_info" href="#meshtastic.tests.test_util.test_support_info">test_support_info</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,731 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.tunnel API documentation</title>
|
||||
<meta name="description" content="Code for IP tunnel over a mesh …" />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.tunnel</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Code for IP tunnel over a mesh</p>
|
||||
<h1 id="note-python-pytuntap-was-too-buggy">Note python-pytuntap was too buggy</h1>
|
||||
<h1 id="using-pip3-install-pytap2">using pip3 install pytap2</h1>
|
||||
<h1 id="make-sure-to-sudo-setcap-cap_net_admineip-usrbinpython38-so-python-can-access-tun-device-without-being-root">make sure to "sudo setcap cap_net_admin+eip /usr/bin/python3.8" so python can access tun device without being root</h1>
|
||||
<h1 id="sudo-ip-tuntap-del-mode-tun-tun0">sudo ip tuntap del mode tun tun0</h1>
|
||||
<h1 id="sudo-binrunsh-port-devttyusb0-setch-shortfast">sudo bin/run.sh –port /dev/ttyUSB0 –setch-shortfast</h1>
|
||||
<h1 id="sudo-binrunsh-port-devttyusb0-tunnel-debug">sudo bin/run.sh –port /dev/ttyUSB0 –tunnel –debug</h1>
|
||||
<h1 id="ssh-y-root19216810151-or-dietpi-default-password-p">ssh -Y root@192.168.10.151 (or dietpi), default password p</h1>
|
||||
<h1 id="ncat-e-bincat-k-u-l-1235">ncat -e /bin/cat -k -u -l 1235</h1>
|
||||
<h1 id="ncat-u-1011564152-1235">ncat -u 10.115.64.152 1235</h1>
|
||||
<h1 id="ping-c-1-w-20-1011564152">ping -c 1 -W 20 10.115.64.152</h1>
|
||||
<h1 id="ping-i-30-w-30-1011564152">ping -i 30 -W 30 10.115.64.152</h1>
|
||||
<h1 id="fixme-use-a-more-optimal-mtu">FIXME: use a more optimal MTU</h1>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Code for IP tunnel over a mesh
|
||||
|
||||
# Note python-pytuntap was too buggy
|
||||
# using pip3 install pytap2
|
||||
# make sure to "sudo setcap cap_net_admin+eip /usr/bin/python3.8" so python can access tun device without being root
|
||||
# sudo ip tuntap del mode tun tun0
|
||||
# sudo bin/run.sh --port /dev/ttyUSB0 --setch-shortfast
|
||||
# sudo bin/run.sh --port /dev/ttyUSB0 --tunnel --debug
|
||||
# ssh -Y root@192.168.10.151 (or dietpi), default password p
|
||||
# ncat -e /bin/cat -k -u -l 1235
|
||||
# ncat -u 10.115.64.152 1235
|
||||
# ping -c 1 -W 20 10.115.64.152
|
||||
# ping -i 30 -W 30 10.115.64.152
|
||||
|
||||
# FIXME: use a more optimal MTU
|
||||
"""
|
||||
|
||||
import logging
|
||||
import threading
|
||||
from pubsub import pub
|
||||
|
||||
from pytap2 import TapDevice
|
||||
|
||||
from . import portnums_pb2
|
||||
|
||||
# A new non standard log level that is lower level than DEBUG
|
||||
LOG_TRACE = 5
|
||||
|
||||
# fixme - find a way to move onTunnelReceive inside of the class
|
||||
tunnelInstance = None
|
||||
|
||||
"""A list of chatty UDP services we should never accidentally
|
||||
forward to our slow network"""
|
||||
udpBlacklist = {
|
||||
1900, # SSDP
|
||||
5353, # multicast DNS
|
||||
}
|
||||
|
||||
"""A list of TCP services to block"""
|
||||
tcpBlacklist = {}
|
||||
|
||||
"""A list of protocols we ignore"""
|
||||
protocolBlacklist = {
|
||||
0x02, # IGMP
|
||||
0x80, # Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment
|
||||
}
|
||||
|
||||
|
||||
def hexstr(barray):
|
||||
"""Print a string of hex digits"""
|
||||
return ":".join('{:02x}'.format(x) for x in barray)
|
||||
|
||||
|
||||
def ipstr(barray):
|
||||
"""Print a string of ip digits"""
|
||||
return ".".join('{}'.format(x) for x in barray)
|
||||
|
||||
|
||||
def readnet_u16(p, offset):
|
||||
"""Read big endian u16 (network byte order)"""
|
||||
return p[offset] * 256 + p[offset + 1]
|
||||
|
||||
|
||||
def onTunnelReceive(packet, interface):
|
||||
"""Callback for received tunneled messages from mesh
|
||||
|
||||
FIXME figure out how to do closures with methods in python"""
|
||||
tunnelInstance.onReceive(packet)
|
||||
|
||||
|
||||
class Tunnel:
|
||||
"""A TUN based IP tunnel over meshtastic"""
|
||||
|
||||
def __init__(self, iface, subnet=None, netmask="255.255.0.0"):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
iface is the already open MeshInterface instance
|
||||
subnet is used to construct our network number (normally 10.115.x.x)
|
||||
"""
|
||||
|
||||
if subnet is None:
|
||||
subnet = "10.115"
|
||||
|
||||
self.iface = iface
|
||||
self.subnetPrefix = subnet
|
||||
|
||||
global tunnelInstance
|
||||
tunnelInstance = self
|
||||
|
||||
logging.info("Starting IP to mesh tunnel (you must be root for this *pre-alpha* "\
|
||||
"feature to work). Mesh members:")
|
||||
|
||||
pub.subscribe(onTunnelReceive, "meshtastic.receive.data.IP_TUNNEL_APP")
|
||||
myAddr = self._nodeNumToIp(self.iface.myInfo.my_node_num)
|
||||
|
||||
for node in self.iface.nodes.values():
|
||||
nodeId = node["user"]["id"]
|
||||
ip = self._nodeNumToIp(node["num"])
|
||||
logging.info(f"Node { nodeId } has IP address { ip }")
|
||||
|
||||
logging.debug("creating TUN device with MTU=200")
|
||||
# FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data
|
||||
self.tun = TapDevice(name="mesh")
|
||||
self.tun.up()
|
||||
self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200)
|
||||
logging.debug(f"starting TUN reader, our IP address is {myAddr}")
|
||||
self._rxThread = threading.Thread(
|
||||
target=self.__tunReader, args=(), daemon=True)
|
||||
self._rxThread.start()
|
||||
|
||||
def onReceive(self, packet):
|
||||
"""onReceive"""
|
||||
p = packet["decoded"]["payload"]
|
||||
if packet["from"] == self.iface.myInfo.my_node_num:
|
||||
logging.debug("Ignoring message we sent")
|
||||
else:
|
||||
logging.debug(
|
||||
f"Received mesh tunnel message type={type(p)} len={len(p)}")
|
||||
# we don't really need to check for filtering here (sender should have checked),
|
||||
# but this provides useful debug printing on types of packets received
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.tun.write(p)
|
||||
|
||||
def _shouldFilterPacket(self, p):
|
||||
"""Given a packet, decode it and return true if it should be ignored"""
|
||||
protocol = p[8 + 1]
|
||||
srcaddr = p[12:16]
|
||||
destAddr = p[16:20]
|
||||
subheader = 20
|
||||
ignore = False # Assume we will be forwarding the packet
|
||||
if protocol in protocolBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}")
|
||||
elif protocol == 0x01: # ICMP
|
||||
icmpType = p[20]
|
||||
icmpCode = p[21]
|
||||
checksum = p[22:24]
|
||||
# pylint: disable=line-too-long
|
||||
logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}")
|
||||
# reply to pings (swap src and dest but keep rest of packet unchanged)
|
||||
#pingback = p[:12]+p[16:20]+p[12:16]+p[20:]
|
||||
# tap.write(pingback)
|
||||
elif protocol == 0x11: # UDP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in udpBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"ignoring blacklisted UDP port {destport}")
|
||||
else:
|
||||
logging.debug(
|
||||
f"forwarding udp srcport={srcport}, destport={destport}")
|
||||
elif protocol == 0x06: # TCP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in tcpBlacklist:
|
||||
ignore = True
|
||||
logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}")
|
||||
else:
|
||||
logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}")
|
||||
else:
|
||||
logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, "\
|
||||
"src={ipstr(srcaddr)}, dest={ipstr(destAddr)}")
|
||||
|
||||
return ignore
|
||||
|
||||
def __tunReader(self):
|
||||
tap = self.tun
|
||||
logging.debug("TUN reader running")
|
||||
while True:
|
||||
p = tap.read()
|
||||
#logging.debug(f"IP packet received on TUN interface, type={type(p)}")
|
||||
destAddr = p[16:20]
|
||||
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.sendPacket(destAddr, p)
|
||||
|
||||
def _ipToNodeId(self, ipAddr):
|
||||
# We only consider the last 16 bits of the nodenum for IP address matching
|
||||
ipBits = ipAddr[2] * 256 + ipAddr[3]
|
||||
|
||||
if ipBits == 0xffff:
|
||||
return "^all"
|
||||
|
||||
for node in self.iface.nodes.values():
|
||||
nodeNum = node["num"] & 0xffff
|
||||
# logging.debug(f"Considering nodenum 0x{nodeNum:x} for ipBits 0x{ipBits:x}")
|
||||
if (nodeNum) == ipBits:
|
||||
return node["user"]["id"]
|
||||
return None
|
||||
|
||||
def _nodeNumToIp(self, nodeNum):
|
||||
return f"{self.subnetPrefix}.{(nodeNum >> 8) & 0xff}.{nodeNum & 0xff}"
|
||||
|
||||
def sendPacket(self, destAddr, p):
|
||||
"""Forward the provided IP packet into the mesh"""
|
||||
nodeId = self._ipToNodeId(destAddr)
|
||||
if nodeId is not None:
|
||||
logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}")
|
||||
self.iface.sendData(
|
||||
p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False)
|
||||
else:
|
||||
logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}")
|
||||
|
||||
def close(self):
|
||||
"""Close"""
|
||||
self.tun.close()</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-variables">Global variables</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tunnel.tcpBlacklist"><code class="name">var <span class="ident">tcpBlacklist</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A list of protocols we ignore</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.tunnelInstance"><code class="name">var <span class="ident">tunnelInstance</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A list of chatty UDP services we should never accidentally
|
||||
forward to our slow network</p></div>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.udpBlacklist"><code class="name">var <span class="ident">udpBlacklist</span></code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A list of TCP services to block</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tunnel.hexstr"><code class="name flex">
|
||||
<span>def <span class="ident">hexstr</span></span>(<span>barray)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Print a string of hex digits</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def hexstr(barray):
|
||||
"""Print a string of hex digits"""
|
||||
return ":".join('{:02x}'.format(x) for x in barray)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.ipstr"><code class="name flex">
|
||||
<span>def <span class="ident">ipstr</span></span>(<span>barray)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Print a string of ip digits</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def ipstr(barray):
|
||||
"""Print a string of ip digits"""
|
||||
return ".".join('{}'.format(x) for x in barray)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.onTunnelReceive"><code class="name flex">
|
||||
<span>def <span class="ident">onTunnelReceive</span></span>(<span>packet, interface)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Callback for received tunneled messages from mesh</p>
|
||||
<p>FIXME figure out how to do closures with methods in python</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onTunnelReceive(packet, interface):
|
||||
"""Callback for received tunneled messages from mesh
|
||||
|
||||
FIXME figure out how to do closures with methods in python"""
|
||||
tunnelInstance.onReceive(packet)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.readnet_u16"><code class="name flex">
|
||||
<span>def <span class="ident">readnet_u16</span></span>(<span>p, offset)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Read big endian u16 (network byte order)</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def readnet_u16(p, offset):
|
||||
"""Read big endian u16 (network byte order)"""
|
||||
return p[offset] * 256 + p[offset + 1]</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.tunnel.Tunnel"><code class="flex name class">
|
||||
<span>class <span class="ident">Tunnel</span></span>
|
||||
<span>(</span><span>iface, subnet=None, netmask='255.255.0.0')</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A TUN based IP tunnel over meshtastic</p>
|
||||
<p>Constructor</p>
|
||||
<p>iface is the already open MeshInterface instance
|
||||
subnet is used to construct our network number (normally 10.115.x.x)</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class Tunnel:
|
||||
"""A TUN based IP tunnel over meshtastic"""
|
||||
|
||||
def __init__(self, iface, subnet=None, netmask="255.255.0.0"):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
iface is the already open MeshInterface instance
|
||||
subnet is used to construct our network number (normally 10.115.x.x)
|
||||
"""
|
||||
|
||||
if subnet is None:
|
||||
subnet = "10.115"
|
||||
|
||||
self.iface = iface
|
||||
self.subnetPrefix = subnet
|
||||
|
||||
global tunnelInstance
|
||||
tunnelInstance = self
|
||||
|
||||
logging.info("Starting IP to mesh tunnel (you must be root for this *pre-alpha* "\
|
||||
"feature to work). Mesh members:")
|
||||
|
||||
pub.subscribe(onTunnelReceive, "meshtastic.receive.data.IP_TUNNEL_APP")
|
||||
myAddr = self._nodeNumToIp(self.iface.myInfo.my_node_num)
|
||||
|
||||
for node in self.iface.nodes.values():
|
||||
nodeId = node["user"]["id"]
|
||||
ip = self._nodeNumToIp(node["num"])
|
||||
logging.info(f"Node { nodeId } has IP address { ip }")
|
||||
|
||||
logging.debug("creating TUN device with MTU=200")
|
||||
# FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data
|
||||
self.tun = TapDevice(name="mesh")
|
||||
self.tun.up()
|
||||
self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200)
|
||||
logging.debug(f"starting TUN reader, our IP address is {myAddr}")
|
||||
self._rxThread = threading.Thread(
|
||||
target=self.__tunReader, args=(), daemon=True)
|
||||
self._rxThread.start()
|
||||
|
||||
def onReceive(self, packet):
|
||||
"""onReceive"""
|
||||
p = packet["decoded"]["payload"]
|
||||
if packet["from"] == self.iface.myInfo.my_node_num:
|
||||
logging.debug("Ignoring message we sent")
|
||||
else:
|
||||
logging.debug(
|
||||
f"Received mesh tunnel message type={type(p)} len={len(p)}")
|
||||
# we don't really need to check for filtering here (sender should have checked),
|
||||
# but this provides useful debug printing on types of packets received
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.tun.write(p)
|
||||
|
||||
def _shouldFilterPacket(self, p):
|
||||
"""Given a packet, decode it and return true if it should be ignored"""
|
||||
protocol = p[8 + 1]
|
||||
srcaddr = p[12:16]
|
||||
destAddr = p[16:20]
|
||||
subheader = 20
|
||||
ignore = False # Assume we will be forwarding the packet
|
||||
if protocol in protocolBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}")
|
||||
elif protocol == 0x01: # ICMP
|
||||
icmpType = p[20]
|
||||
icmpCode = p[21]
|
||||
checksum = p[22:24]
|
||||
# pylint: disable=line-too-long
|
||||
logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}")
|
||||
# reply to pings (swap src and dest but keep rest of packet unchanged)
|
||||
#pingback = p[:12]+p[16:20]+p[12:16]+p[20:]
|
||||
# tap.write(pingback)
|
||||
elif protocol == 0x11: # UDP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in udpBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"ignoring blacklisted UDP port {destport}")
|
||||
else:
|
||||
logging.debug(
|
||||
f"forwarding udp srcport={srcport}, destport={destport}")
|
||||
elif protocol == 0x06: # TCP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in tcpBlacklist:
|
||||
ignore = True
|
||||
logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}")
|
||||
else:
|
||||
logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}")
|
||||
else:
|
||||
logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, "\
|
||||
"src={ipstr(srcaddr)}, dest={ipstr(destAddr)}")
|
||||
|
||||
return ignore
|
||||
|
||||
def __tunReader(self):
|
||||
tap = self.tun
|
||||
logging.debug("TUN reader running")
|
||||
while True:
|
||||
p = tap.read()
|
||||
#logging.debug(f"IP packet received on TUN interface, type={type(p)}")
|
||||
destAddr = p[16:20]
|
||||
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.sendPacket(destAddr, p)
|
||||
|
||||
def _ipToNodeId(self, ipAddr):
|
||||
# We only consider the last 16 bits of the nodenum for IP address matching
|
||||
ipBits = ipAddr[2] * 256 + ipAddr[3]
|
||||
|
||||
if ipBits == 0xffff:
|
||||
return "^all"
|
||||
|
||||
for node in self.iface.nodes.values():
|
||||
nodeNum = node["num"] & 0xffff
|
||||
# logging.debug(f"Considering nodenum 0x{nodeNum:x} for ipBits 0x{ipBits:x}")
|
||||
if (nodeNum) == ipBits:
|
||||
return node["user"]["id"]
|
||||
return None
|
||||
|
||||
def _nodeNumToIp(self, nodeNum):
|
||||
return f"{self.subnetPrefix}.{(nodeNum >> 8) & 0xff}.{nodeNum & 0xff}"
|
||||
|
||||
def sendPacket(self, destAddr, p):
|
||||
"""Forward the provided IP packet into the mesh"""
|
||||
nodeId = self._ipToNodeId(destAddr)
|
||||
if nodeId is not None:
|
||||
logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}")
|
||||
self.iface.sendData(
|
||||
p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False)
|
||||
else:
|
||||
logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}")
|
||||
|
||||
def close(self):
|
||||
"""Close"""
|
||||
self.tun.close()</code></pre>
|
||||
</details>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.tunnel.Tunnel._Tunnel__tunReader"><code class="name flex">
|
||||
<span>def <span class="ident">_Tunnel__tunReader</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def __tunReader(self):
|
||||
tap = self.tun
|
||||
logging.debug("TUN reader running")
|
||||
while True:
|
||||
p = tap.read()
|
||||
#logging.debug(f"IP packet received on TUN interface, type={type(p)}")
|
||||
destAddr = p[16:20]
|
||||
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.sendPacket(destAddr, p)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel._ipToNodeId"><code class="name flex">
|
||||
<span>def <span class="ident">_ipToNodeId</span></span>(<span>self, ipAddr)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _ipToNodeId(self, ipAddr):
|
||||
# We only consider the last 16 bits of the nodenum for IP address matching
|
||||
ipBits = ipAddr[2] * 256 + ipAddr[3]
|
||||
|
||||
if ipBits == 0xffff:
|
||||
return "^all"
|
||||
|
||||
for node in self.iface.nodes.values():
|
||||
nodeNum = node["num"] & 0xffff
|
||||
# logging.debug(f"Considering nodenum 0x{nodeNum:x} for ipBits 0x{ipBits:x}")
|
||||
if (nodeNum) == ipBits:
|
||||
return node["user"]["id"]
|
||||
return None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel._nodeNumToIp"><code class="name flex">
|
||||
<span>def <span class="ident">_nodeNumToIp</span></span>(<span>self, nodeNum)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _nodeNumToIp(self, nodeNum):
|
||||
return f"{self.subnetPrefix}.{(nodeNum >> 8) & 0xff}.{nodeNum & 0xff}"</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel._shouldFilterPacket"><code class="name flex">
|
||||
<span>def <span class="ident">_shouldFilterPacket</span></span>(<span>self, p)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Given a packet, decode it and return true if it should be ignored</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _shouldFilterPacket(self, p):
|
||||
"""Given a packet, decode it and return true if it should be ignored"""
|
||||
protocol = p[8 + 1]
|
||||
srcaddr = p[12:16]
|
||||
destAddr = p[16:20]
|
||||
subheader = 20
|
||||
ignore = False # Assume we will be forwarding the packet
|
||||
if protocol in protocolBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}")
|
||||
elif protocol == 0x01: # ICMP
|
||||
icmpType = p[20]
|
||||
icmpCode = p[21]
|
||||
checksum = p[22:24]
|
||||
# pylint: disable=line-too-long
|
||||
logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}")
|
||||
# reply to pings (swap src and dest but keep rest of packet unchanged)
|
||||
#pingback = p[:12]+p[16:20]+p[12:16]+p[20:]
|
||||
# tap.write(pingback)
|
||||
elif protocol == 0x11: # UDP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in udpBlacklist:
|
||||
ignore = True
|
||||
logging.log(
|
||||
LOG_TRACE, f"ignoring blacklisted UDP port {destport}")
|
||||
else:
|
||||
logging.debug(
|
||||
f"forwarding udp srcport={srcport}, destport={destport}")
|
||||
elif protocol == 0x06: # TCP
|
||||
srcport = readnet_u16(p, subheader)
|
||||
destport = readnet_u16(p, subheader + 2)
|
||||
if destport in tcpBlacklist:
|
||||
ignore = True
|
||||
logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}")
|
||||
else:
|
||||
logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}")
|
||||
else:
|
||||
logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, "\
|
||||
"src={ipstr(srcaddr)}, dest={ipstr(destAddr)}")
|
||||
|
||||
return ignore</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel.close"><code class="name flex">
|
||||
<span>def <span class="ident">close</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Close</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def close(self):
|
||||
"""Close"""
|
||||
self.tun.close()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel.onReceive"><code class="name flex">
|
||||
<span>def <span class="ident">onReceive</span></span>(<span>self, packet)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>onReceive</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def onReceive(self, packet):
|
||||
"""onReceive"""
|
||||
p = packet["decoded"]["payload"]
|
||||
if packet["from"] == self.iface.myInfo.my_node_num:
|
||||
logging.debug("Ignoring message we sent")
|
||||
else:
|
||||
logging.debug(
|
||||
f"Received mesh tunnel message type={type(p)} len={len(p)}")
|
||||
# we don't really need to check for filtering here (sender should have checked),
|
||||
# but this provides useful debug printing on types of packets received
|
||||
if not self._shouldFilterPacket(p):
|
||||
self.tun.write(p)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.tunnel.Tunnel.sendPacket"><code class="name flex">
|
||||
<span>def <span class="ident">sendPacket</span></span>(<span>self, destAddr, p)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Forward the provided IP packet into the mesh</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def sendPacket(self, destAddr, p):
|
||||
"""Forward the provided IP packet into the mesh"""
|
||||
nodeId = self._ipToNodeId(destAddr)
|
||||
if nodeId is not None:
|
||||
logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}")
|
||||
self.iface.sendData(
|
||||
p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False)
|
||||
else:
|
||||
logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul>
|
||||
<li><a href="#note-python-pytuntap-was-too-buggy">Note python-pytuntap was too buggy</a></li>
|
||||
<li><a href="#using-pip3-install-pytap2">using pip3 install pytap2</a></li>
|
||||
<li><a href="#make-sure-to-sudo-setcap-cap_net_admineip-usrbinpython38-so-python-can-access-tun-device-without-being-root">make sure to "sudo setcap cap_net_admin+eip /usr/bin/python3.8" so python can access tun device without being root</a></li>
|
||||
<li><a href="#sudo-ip-tuntap-del-mode-tun-tun0">sudo ip tuntap del mode tun tun0</a></li>
|
||||
<li><a href="#sudo-binrunsh-port-devttyusb0-setch-shortfast">sudo bin/run.sh –port /dev/ttyUSB0 –setch-shortfast</a></li>
|
||||
<li><a href="#sudo-binrunsh-port-devttyusb0-tunnel-debug">sudo bin/run.sh –port /dev/ttyUSB0 –tunnel –debug</a></li>
|
||||
<li><a href="#ssh-y-root19216810151-or-dietpi-default-password-p">ssh -Y root@192.168.10.151 (or dietpi), default password p</a></li>
|
||||
<li><a href="#ncat-e-bincat-k-u-l-1235">ncat -e /bin/cat -k -u -l 1235</a></li>
|
||||
<li><a href="#ncat-u-1011564152-1235">ncat -u 10.115.64.152 1235</a></li>
|
||||
<li><a href="#ping-c-1-w-20-1011564152">ping -c 1 -W 20 10.115.64.152</a></li>
|
||||
<li><a href="#ping-i-30-w-30-1011564152">ping -i 30 -W 30 10.115.64.152</a></li>
|
||||
<li><a href="#fixme-use-a-more-optimal-mtu">FIXME: use a more optimal MTU</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-variables">Global variables</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tunnel.tcpBlacklist" href="#meshtastic.tunnel.tcpBlacklist">tcpBlacklist</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.tunnelInstance" href="#meshtastic.tunnel.tunnelInstance">tunnelInstance</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.udpBlacklist" href="#meshtastic.tunnel.udpBlacklist">udpBlacklist</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.tunnel.hexstr" href="#meshtastic.tunnel.hexstr">hexstr</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.ipstr" href="#meshtastic.tunnel.ipstr">ipstr</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.onTunnelReceive" href="#meshtastic.tunnel.onTunnelReceive">onTunnelReceive</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.readnet_u16" href="#meshtastic.tunnel.readnet_u16">readnet_u16</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.tunnel.Tunnel" href="#meshtastic.tunnel.Tunnel">Tunnel</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel._Tunnel__tunReader" href="#meshtastic.tunnel.Tunnel._Tunnel__tunReader">_Tunnel__tunReader</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel._ipToNodeId" href="#meshtastic.tunnel.Tunnel._ipToNodeId">_ipToNodeId</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel._nodeNumToIp" href="#meshtastic.tunnel.Tunnel._nodeNumToIp">_nodeNumToIp</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel._shouldFilterPacket" href="#meshtastic.tunnel.Tunnel._shouldFilterPacket">_shouldFilterPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel.close" href="#meshtastic.tunnel.Tunnel.close">close</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel.onReceive" href="#meshtastic.tunnel.Tunnel.onReceive">onReceive</a></code></li>
|
||||
<li><code><a title="meshtastic.tunnel.Tunnel.sendPacket" href="#meshtastic.tunnel.Tunnel.sendPacket">sendPacket</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,709 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="generator" content="pdoc 0.10.1.dev1+g4aa70de.d20211229" />
|
||||
<title>meshtastic.util API documentation</title>
|
||||
<meta name="description" content="Utility functions." />
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
|
||||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
|
||||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
|
||||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
|
||||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
|
||||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<article id="content">
|
||||
<header>
|
||||
<h1 class="title">Module <code>meshtastic.util</code></h1>
|
||||
</header>
|
||||
<section id="section-intro">
|
||||
<p>Utility functions.</p>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">"""Utility functions.
|
||||
"""
|
||||
import traceback
|
||||
from queue import Queue
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import platform
|
||||
import logging
|
||||
import threading
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import pkg_resources
|
||||
|
||||
"""Some devices such as a seger jlink we never want to accidentally open"""
|
||||
blacklistVids = dict.fromkeys([0x1366])
|
||||
|
||||
|
||||
def quoteBooleans(a_string):
|
||||
"""Quote booleans
|
||||
given a string that contains ": true", replace with ": 'true'" (or false)
|
||||
"""
|
||||
tmp = a_string.replace(": true", ": 'true'")
|
||||
tmp = tmp.replace(": false", ": 'false'")
|
||||
return tmp
|
||||
|
||||
def genPSK256():
|
||||
"""Generate a random preshared key"""
|
||||
return os.urandom(32)
|
||||
|
||||
|
||||
def fromPSK(valstr):
|
||||
"""A special version of fromStr that assumes the user is trying to set a PSK.
|
||||
In that case we also allow "none", "default" or "random" (to have python generate one), or simpleN
|
||||
"""
|
||||
if valstr == "random":
|
||||
return genPSK256()
|
||||
elif valstr == "none":
|
||||
return bytes([0]) # Use the 'no encryption' PSK
|
||||
elif valstr == "default":
|
||||
return bytes([1]) # Use default channel psk
|
||||
elif valstr.startswith("simple"):
|
||||
# Use one of the single byte encodings
|
||||
return bytes([int(valstr[6:]) + 1])
|
||||
else:
|
||||
return fromStr(valstr)
|
||||
|
||||
|
||||
def fromStr(valstr):
|
||||
"""Try to parse as int, float or bool (and fallback to a string as last resort)
|
||||
|
||||
Returns: an int, bool, float, str or byte array (for strings of hex digits)
|
||||
|
||||
Args:
|
||||
valstr (string): A user provided string
|
||||
"""
|
||||
if len(valstr) == 0: # Treat an emptystring as an empty bytes
|
||||
val = bytes()
|
||||
elif valstr.startswith('0x'):
|
||||
# if needed convert to string with asBytes.decode('utf-8')
|
||||
val = bytes.fromhex(valstr[2:])
|
||||
elif valstr.lower() in {"t", "true", "yes"}:
|
||||
val = True
|
||||
elif valstr.lower() in {"f", "false", "no"}:
|
||||
val = False
|
||||
else:
|
||||
try:
|
||||
val = int(valstr)
|
||||
except ValueError:
|
||||
try:
|
||||
val = float(valstr)
|
||||
except ValueError:
|
||||
val = valstr # Not a float or an int, assume string
|
||||
return val
|
||||
|
||||
|
||||
def pskToString(psk: bytes):
|
||||
"""Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string"""
|
||||
if len(psk) == 0:
|
||||
return "unencrypted"
|
||||
elif len(psk) == 1:
|
||||
b = psk[0]
|
||||
if b == 0:
|
||||
return "unencrypted"
|
||||
elif b == 1:
|
||||
return "default"
|
||||
else:
|
||||
return f"simple{b - 1}"
|
||||
else:
|
||||
return "secret"
|
||||
|
||||
|
||||
def stripnl(s):
|
||||
"""Remove newlines from a string (and remove extra whitespace)"""
|
||||
s = str(s).replace("\n", " ")
|
||||
return ' '.join(s.split())
|
||||
|
||||
|
||||
def fixme(message):
|
||||
"""Raise an exception for things that needs to be fixed"""
|
||||
raise Exception(f"FIXME: {message}")
|
||||
|
||||
|
||||
def catchAndIgnore(reason, closure):
|
||||
"""Call a closure but if it throws an exception print it and continue"""
|
||||
try:
|
||||
closure()
|
||||
except BaseException as ex:
|
||||
logging.error(f"Exception thrown in {reason}: {ex}")
|
||||
|
||||
|
||||
def findPorts():
|
||||
"""Find all ports that might have meshtastic devices
|
||||
|
||||
Returns:
|
||||
list -- a list of device paths
|
||||
"""
|
||||
l = 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())))
|
||||
l.sort()
|
||||
return l
|
||||
|
||||
|
||||
class dotdict(dict):
|
||||
"""dot.notation access to dictionary attributes"""
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__
|
||||
|
||||
|
||||
class Timeout:
|
||||
"""Timeout class"""
|
||||
def __init__(self, maxSecs=20):
|
||||
self.expireTime = 0
|
||||
self.sleepInterval = 0.1
|
||||
self.expireTimeout = maxSecs
|
||||
|
||||
def reset(self):
|
||||
"""Restart the waitForSet timer"""
|
||||
self.expireTime = time.time() + self.expireTimeout
|
||||
|
||||
def waitForSet(self, target, attrs=()):
|
||||
"""Block until the specified attributes are set. Returns True if config has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
if all(map(lambda a: getattr(target, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(self.sleepInterval)
|
||||
return False
|
||||
|
||||
|
||||
class DeferredExecution():
|
||||
"""A thread that accepts closures to run, and runs them as they are received"""
|
||||
|
||||
def __init__(self, name=None):
|
||||
self.queue = Queue()
|
||||
self.thread = threading.Thread(target=self._run, args=(), name=name)
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def queueWork(self, runnable):
|
||||
""" Queue up the work"""
|
||||
self.queue.put(runnable)
|
||||
|
||||
def _run(self):
|
||||
while True:
|
||||
try:
|
||||
o = self.queue.get()
|
||||
o()
|
||||
except:
|
||||
logging.error(
|
||||
f"Unexpected error in deferred execution {sys.exc_info()[0]}")
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
||||
def our_exit(message, return_value = 1):
|
||||
"""Print the message and return a value.
|
||||
return_value defaults to 1 (non-successful)
|
||||
"""
|
||||
print(message)
|
||||
sys.exit(return_value)
|
||||
|
||||
|
||||
def support_info():
|
||||
"""Print out info that helps troubleshooting of the cli."""
|
||||
print('')
|
||||
print('If having issues with meshtastic cli or python library')
|
||||
print('or wish to make feature requests, visit:')
|
||||
print('https://github.com/meshtastic/Meshtastic-python/issues')
|
||||
print('When adding an issue, be sure to include the following info:')
|
||||
print(' System: {0}'.format(platform.system()))
|
||||
print(' Platform: {0}'.format(platform.platform()))
|
||||
print(' Release: {0}'.format(platform.uname().release))
|
||||
print(' Machine: {0}'.format(platform.uname().machine))
|
||||
print(' Encoding (stdin): {0}'.format(sys.stdin.encoding))
|
||||
print(' Encoding (stdout): {0}'.format(sys.stdout.encoding))
|
||||
print(' meshtastic: v{0}'.format(pkg_resources.require('meshtastic')[0].version))
|
||||
print(' Executable: {0}'.format(sys.argv[0]))
|
||||
print(' Python: {0} {1} {2}'.format(platform.python_version(),
|
||||
platform.python_implementation(), platform.python_compiler()))
|
||||
print('')
|
||||
print('Please add the output from the command: meshtastic --info')</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.util.catchAndIgnore"><code class="name flex">
|
||||
<span>def <span class="ident">catchAndIgnore</span></span>(<span>reason, closure)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Call a closure but if it throws an exception print it and continue</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def catchAndIgnore(reason, closure):
|
||||
"""Call a closure but if it throws an exception print it and continue"""
|
||||
try:
|
||||
closure()
|
||||
except BaseException as ex:
|
||||
logging.error(f"Exception thrown in {reason}: {ex}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.findPorts"><code class="name flex">
|
||||
<span>def <span class="ident">findPorts</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Find all ports that might have meshtastic devices</p>
|
||||
<h2 id="returns">Returns</h2>
|
||||
<p>list – a list of device paths</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def findPorts():
|
||||
"""Find all ports that might have meshtastic devices
|
||||
|
||||
Returns:
|
||||
list -- a list of device paths
|
||||
"""
|
||||
l = 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())))
|
||||
l.sort()
|
||||
return l</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.fixme"><code class="name flex">
|
||||
<span>def <span class="ident">fixme</span></span>(<span>message)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Raise an exception for things that needs to be fixed</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def fixme(message):
|
||||
"""Raise an exception for things that needs to be fixed"""
|
||||
raise Exception(f"FIXME: {message}")</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.fromPSK"><code class="name flex">
|
||||
<span>def <span class="ident">fromPSK</span></span>(<span>valstr)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A special version of fromStr that assumes the user is trying to set a PSK.
|
||||
In that case we also allow "none", "default" or "random" (to have python generate one), or simpleN</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def fromPSK(valstr):
|
||||
"""A special version of fromStr that assumes the user is trying to set a PSK.
|
||||
In that case we also allow "none", "default" or "random" (to have python generate one), or simpleN
|
||||
"""
|
||||
if valstr == "random":
|
||||
return genPSK256()
|
||||
elif valstr == "none":
|
||||
return bytes([0]) # Use the 'no encryption' PSK
|
||||
elif valstr == "default":
|
||||
return bytes([1]) # Use default channel psk
|
||||
elif valstr.startswith("simple"):
|
||||
# Use one of the single byte encodings
|
||||
return bytes([int(valstr[6:]) + 1])
|
||||
else:
|
||||
return fromStr(valstr)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.fromStr"><code class="name flex">
|
||||
<span>def <span class="ident">fromStr</span></span>(<span>valstr)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Try to parse as int, float or bool (and fallback to a string as last resort)</p>
|
||||
<p>Returns: an int, bool, float, str or byte array (for strings of hex digits)</p>
|
||||
<h2 id="args">Args</h2>
|
||||
<dl>
|
||||
<dt><strong><code>valstr</code></strong> : <code>string</code></dt>
|
||||
<dd>A user provided string</dd>
|
||||
</dl></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def fromStr(valstr):
|
||||
"""Try to parse as int, float or bool (and fallback to a string as last resort)
|
||||
|
||||
Returns: an int, bool, float, str or byte array (for strings of hex digits)
|
||||
|
||||
Args:
|
||||
valstr (string): A user provided string
|
||||
"""
|
||||
if len(valstr) == 0: # Treat an emptystring as an empty bytes
|
||||
val = bytes()
|
||||
elif valstr.startswith('0x'):
|
||||
# if needed convert to string with asBytes.decode('utf-8')
|
||||
val = bytes.fromhex(valstr[2:])
|
||||
elif valstr.lower() in {"t", "true", "yes"}:
|
||||
val = True
|
||||
elif valstr.lower() in {"f", "false", "no"}:
|
||||
val = False
|
||||
else:
|
||||
try:
|
||||
val = int(valstr)
|
||||
except ValueError:
|
||||
try:
|
||||
val = float(valstr)
|
||||
except ValueError:
|
||||
val = valstr # Not a float or an int, assume string
|
||||
return val</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.genPSK256"><code class="name flex">
|
||||
<span>def <span class="ident">genPSK256</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Generate a random preshared key</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def genPSK256():
|
||||
"""Generate a random preshared key"""
|
||||
return os.urandom(32)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.our_exit"><code class="name flex">
|
||||
<span>def <span class="ident">our_exit</span></span>(<span>message, return_value=1)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Print the message and return a value.
|
||||
return_value defaults to 1 (non-successful)</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def our_exit(message, return_value = 1):
|
||||
"""Print the message and return a value.
|
||||
return_value defaults to 1 (non-successful)
|
||||
"""
|
||||
print(message)
|
||||
sys.exit(return_value)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.pskToString"><code class="name flex">
|
||||
<span>def <span class="ident">pskToString</span></span>(<span>psk: bytes)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def pskToString(psk: bytes):
|
||||
"""Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string"""
|
||||
if len(psk) == 0:
|
||||
return "unencrypted"
|
||||
elif len(psk) == 1:
|
||||
b = psk[0]
|
||||
if b == 0:
|
||||
return "unencrypted"
|
||||
elif b == 1:
|
||||
return "default"
|
||||
else:
|
||||
return f"simple{b - 1}"
|
||||
else:
|
||||
return "secret"</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.quoteBooleans"><code class="name flex">
|
||||
<span>def <span class="ident">quoteBooleans</span></span>(<span>a_string)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Quote booleans
|
||||
given a string that contains ": true", replace with ": 'true'" (or false)</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def quoteBooleans(a_string):
|
||||
"""Quote booleans
|
||||
given a string that contains ": true", replace with ": 'true'" (or false)
|
||||
"""
|
||||
tmp = a_string.replace(": true", ": 'true'")
|
||||
tmp = tmp.replace(": false", ": 'false'")
|
||||
return tmp</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.stripnl"><code class="name flex">
|
||||
<span>def <span class="ident">stripnl</span></span>(<span>s)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Remove newlines from a string (and remove extra whitespace)</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def stripnl(s):
|
||||
"""Remove newlines from a string (and remove extra whitespace)"""
|
||||
s = str(s).replace("\n", " ")
|
||||
return ' '.join(s.split())</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.support_info"><code class="name flex">
|
||||
<span>def <span class="ident">support_info</span></span>(<span>)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Print out info that helps troubleshooting of the cli.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def support_info():
|
||||
"""Print out info that helps troubleshooting of the cli."""
|
||||
print('')
|
||||
print('If having issues with meshtastic cli or python library')
|
||||
print('or wish to make feature requests, visit:')
|
||||
print('https://github.com/meshtastic/Meshtastic-python/issues')
|
||||
print('When adding an issue, be sure to include the following info:')
|
||||
print(' System: {0}'.format(platform.system()))
|
||||
print(' Platform: {0}'.format(platform.platform()))
|
||||
print(' Release: {0}'.format(platform.uname().release))
|
||||
print(' Machine: {0}'.format(platform.uname().machine))
|
||||
print(' Encoding (stdin): {0}'.format(sys.stdin.encoding))
|
||||
print(' Encoding (stdout): {0}'.format(sys.stdout.encoding))
|
||||
print(' meshtastic: v{0}'.format(pkg_resources.require('meshtastic')[0].version))
|
||||
print(' Executable: {0}'.format(sys.argv[0]))
|
||||
print(' Python: {0} {1} {2}'.format(platform.python_version(),
|
||||
platform.python_implementation(), platform.python_compiler()))
|
||||
print('')
|
||||
print('Please add the output from the command: meshtastic --info')</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="meshtastic.util.DeferredExecution"><code class="flex name class">
|
||||
<span>class <span class="ident">DeferredExecution</span></span>
|
||||
<span>(</span><span>name=None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>A thread that accepts closures to run, and runs them as they are received</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class DeferredExecution():
|
||||
"""A thread that accepts closures to run, and runs them as they are received"""
|
||||
|
||||
def __init__(self, name=None):
|
||||
self.queue = Queue()
|
||||
self.thread = threading.Thread(target=self._run, args=(), name=name)
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def queueWork(self, runnable):
|
||||
""" Queue up the work"""
|
||||
self.queue.put(runnable)
|
||||
|
||||
def _run(self):
|
||||
while True:
|
||||
try:
|
||||
o = self.queue.get()
|
||||
o()
|
||||
except:
|
||||
logging.error(
|
||||
f"Unexpected error in deferred execution {sys.exc_info()[0]}")
|
||||
print(traceback.format_exc())</code></pre>
|
||||
</details>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.util.DeferredExecution._run"><code class="name flex">
|
||||
<span>def <span class="ident">_run</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def _run(self):
|
||||
while True:
|
||||
try:
|
||||
o = self.queue.get()
|
||||
o()
|
||||
except:
|
||||
logging.error(
|
||||
f"Unexpected error in deferred execution {sys.exc_info()[0]}")
|
||||
print(traceback.format_exc())</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.DeferredExecution.queueWork"><code class="name flex">
|
||||
<span>def <span class="ident">queueWork</span></span>(<span>self, runnable)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Queue up the work</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def queueWork(self, runnable):
|
||||
""" Queue up the work"""
|
||||
self.queue.put(runnable)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.Timeout"><code class="flex name class">
|
||||
<span>class <span class="ident">Timeout</span></span>
|
||||
<span>(</span><span>maxSecs=20)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Timeout class</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class Timeout:
|
||||
"""Timeout class"""
|
||||
def __init__(self, maxSecs=20):
|
||||
self.expireTime = 0
|
||||
self.sleepInterval = 0.1
|
||||
self.expireTimeout = maxSecs
|
||||
|
||||
def reset(self):
|
||||
"""Restart the waitForSet timer"""
|
||||
self.expireTime = time.time() + self.expireTimeout
|
||||
|
||||
def waitForSet(self, target, attrs=()):
|
||||
"""Block until the specified attributes are set. Returns True if config has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
if all(map(lambda a: getattr(target, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(self.sleepInterval)
|
||||
return False</code></pre>
|
||||
</details>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.util.Timeout.reset"><code class="name flex">
|
||||
<span>def <span class="ident">reset</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Restart the waitForSet timer</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def reset(self):
|
||||
"""Restart the waitForSet timer"""
|
||||
self.expireTime = time.time() + self.expireTimeout</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.Timeout.waitForSet"><code class="name flex">
|
||||
<span>def <span class="ident">waitForSet</span></span>(<span>self, target, attrs=())</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Block until the specified attributes are set. Returns True if config has been received.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def waitForSet(self, target, attrs=()):
|
||||
"""Block until the specified attributes are set. Returns True if config has been received."""
|
||||
self.reset()
|
||||
while time.time() < self.expireTime:
|
||||
if all(map(lambda a: getattr(target, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(self.sleepInterval)
|
||||
return False</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="meshtastic.util.dotdict"><code class="flex name class">
|
||||
<span>class <span class="ident">dotdict</span></span>
|
||||
<span>(</span><span>*args, **kwargs)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>dot.notation access to dictionary attributes</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class dotdict(dict):
|
||||
"""dot.notation access to dictionary attributes"""
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__</code></pre>
|
||||
</details>
|
||||
<h3>Ancestors</h3>
|
||||
<ul class="hlist">
|
||||
<li>builtins.dict</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
<nav id="sidebar">
|
||||
<h1>Index</h1>
|
||||
<div class="toc">
|
||||
<ul></ul>
|
||||
</div>
|
||||
<ul id="index">
|
||||
<li><h3>Super-module</h3>
|
||||
<ul>
|
||||
<li><code><a title="meshtastic" href="index.html">meshtastic</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.util.catchAndIgnore" href="#meshtastic.util.catchAndIgnore">catchAndIgnore</a></code></li>
|
||||
<li><code><a title="meshtastic.util.findPorts" href="#meshtastic.util.findPorts">findPorts</a></code></li>
|
||||
<li><code><a title="meshtastic.util.fixme" href="#meshtastic.util.fixme">fixme</a></code></li>
|
||||
<li><code><a title="meshtastic.util.fromPSK" href="#meshtastic.util.fromPSK">fromPSK</a></code></li>
|
||||
<li><code><a title="meshtastic.util.fromStr" href="#meshtastic.util.fromStr">fromStr</a></code></li>
|
||||
<li><code><a title="meshtastic.util.genPSK256" href="#meshtastic.util.genPSK256">genPSK256</a></code></li>
|
||||
<li><code><a title="meshtastic.util.our_exit" href="#meshtastic.util.our_exit">our_exit</a></code></li>
|
||||
<li><code><a title="meshtastic.util.pskToString" href="#meshtastic.util.pskToString">pskToString</a></code></li>
|
||||
<li><code><a title="meshtastic.util.quoteBooleans" href="#meshtastic.util.quoteBooleans">quoteBooleans</a></code></li>
|
||||
<li><code><a title="meshtastic.util.stripnl" href="#meshtastic.util.stripnl">stripnl</a></code></li>
|
||||
<li><code><a title="meshtastic.util.support_info" href="#meshtastic.util.support_info">support_info</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.util.DeferredExecution" href="#meshtastic.util.DeferredExecution">DeferredExecution</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.util.DeferredExecution._run" href="#meshtastic.util.DeferredExecution._run">_run</a></code></li>
|
||||
<li><code><a title="meshtastic.util.DeferredExecution.queueWork" href="#meshtastic.util.DeferredExecution.queueWork">queueWork</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.util.Timeout" href="#meshtastic.util.Timeout">Timeout</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="meshtastic.util.Timeout.reset" href="#meshtastic.util.Timeout.reset">reset</a></code></li>
|
||||
<li><code><a title="meshtastic.util.Timeout.waitForSet" href="#meshtastic.util.Timeout.waitForSet">waitForSet</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="meshtastic.util.dotdict" href="#meshtastic.util.dotdict">dotdict</a></code></h4>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</main>
|
||||
<footer id="footer">
|
||||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.1.dev1+g4aa70de.d20211229</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,389 +0,0 @@
|
||||
# Python API Commands Guide
|
||||
|
||||
The python pip package installs a "meshtastic" command line executable, which displays packets sent over the network as JSON and lets you see serial debugging information from the meshtastic devices. This command is not run inside of python, you run it from your operating system shell prompt directly. If when you type "meshtastic" it doesn't find the command and you are using Windows: Check that the python "scripts" directory is in your path.
|
||||
|
||||
## Optional Arguments
|
||||
|
||||
### -h or --help
|
||||
|
||||
Shows a help message that describes the arguments.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic -h
|
||||
```
|
||||
|
||||
### --port PORT
|
||||
|
||||
The port the Meshtastic device is connected to, i.e. /dev/ttyUSB0 or COM4. if unspecified, meshtastic will try to find it. Important to use when multiple devices are connected to ensure you call the command for the correct device.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --info
|
||||
meshtastic --port COM4 --info
|
||||
```
|
||||
|
||||
### --host HOST
|
||||
|
||||
The hostname/ipaddr of the device to connect to (over TCP).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --host HOST
|
||||
```
|
||||
|
||||
### --seriallog SERIALLOG
|
||||
|
||||
Logs device serial output to either 'stdout', 'none' or a filename to append to.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --seriallog
|
||||
```
|
||||
|
||||
### --info
|
||||
|
||||
Read and display the radio config information.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --info
|
||||
```
|
||||
|
||||
### --nodes
|
||||
|
||||
Prints a node list in a pretty, formatted table.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --nodes
|
||||
```
|
||||
|
||||
### --qr
|
||||
|
||||
Displays the QR code that corresponds to the current channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --qr
|
||||
```
|
||||
|
||||
### --get GET
|
||||
|
||||
Gets a preferences field.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --get modem_config
|
||||
```
|
||||
|
||||
### --set SET SET
|
||||
|
||||
Sets a preferences field.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --set region Unset
|
||||
```
|
||||
|
||||
### --seturl SETURL
|
||||
|
||||
Set a channel URL.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --seturl https://www.meshtastic.org/c/GAMiIE67C6zsNmlWQ-KE1tKt0fRKFciHka-DShI6G7ElvGOiKgZzaGFyZWQ=
|
||||
```
|
||||
|
||||
### --ch-index CH_INDEX
|
||||
|
||||
Set the specified channel index
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-index 1 --ch-disable
|
||||
```
|
||||
|
||||
### --ch-add CH_ADD
|
||||
|
||||
Add a secondary channel, you must specify a channel name.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-add testing-channel
|
||||
```
|
||||
### --ch-del
|
||||
|
||||
Delete the ch-index channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-index 1 --ch-del
|
||||
```
|
||||
|
||||
### --ch-enable
|
||||
|
||||
Enable the specified channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-index 1 --ch-enable
|
||||
```
|
||||
|
||||
### --ch-disable
|
||||
|
||||
Disable the specified channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-index 1 --ch-disable
|
||||
```
|
||||
|
||||
### --ch-set CH_SET CH_SET
|
||||
|
||||
Set a channel parameter.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-set id 1234
|
||||
```
|
||||
|
||||
### --ch-longslow
|
||||
|
||||
Change to the standard long-range (but slow) channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-longslow
|
||||
```
|
||||
|
||||
### --ch-shortfast
|
||||
|
||||
Change to the standard fast (but short range) channel.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ch-shortfast
|
||||
```
|
||||
|
||||
### --set-owner SET_OWNER
|
||||
|
||||
Set device owner name.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --dest \!28979058 --set-owner "MeshyJohn"
|
||||
```
|
||||
|
||||
### --set-ham SET_HAM
|
||||
|
||||
Set licensed Ham ID and turn off encryption.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --set-ham KI1345
|
||||
```
|
||||
|
||||
### --dest DEST
|
||||
|
||||
The destination node id for any sent commands
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --dest \!28979058 --set-owner "MeshyJohn"
|
||||
```
|
||||
|
||||
### --sendtext SENDTEXT
|
||||
|
||||
Send a text message.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --sendtext "Hello Mesh!"
|
||||
```
|
||||
|
||||
### --sendping
|
||||
|
||||
Send a ping message (which requests a reply).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --sendping
|
||||
```
|
||||
|
||||
### --reboot
|
||||
|
||||
Tell the destination node to reboot.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --dest \!28979058 --reboot
|
||||
```
|
||||
|
||||
### --reply
|
||||
|
||||
Reply to received messages.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --reply
|
||||
```
|
||||
|
||||
### --gpio-wrb GPIO_WRB GPIO_WRB
|
||||
|
||||
Set a particular GPIO # to 1 or 0.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 1 --dest \!28979058
|
||||
```
|
||||
|
||||
### --gpio-rd GPIO_RD
|
||||
|
||||
Read from a GPIO mask.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --gpio-rd 0x10 --dest \!28979058
|
||||
```
|
||||
|
||||
### --gpio-watch GPIO_WATCH
|
||||
|
||||
Start watching a GPIO mask for changes.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --gpio-watch 0x10 --dest \!28979058
|
||||
```
|
||||
|
||||
### --no-time
|
||||
|
||||
Suppress sending the current time to the mesh.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --port /dev/ttyUSB0 --no-time
|
||||
```
|
||||
|
||||
### --setalt SETALT
|
||||
|
||||
Set device altitude (allows use without GPS).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --setalt 120
|
||||
```
|
||||
|
||||
### --setlat SETLAT
|
||||
|
||||
Set device latitude (allows use without GPS).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --setlat 25.2
|
||||
```
|
||||
|
||||
### --setlon SETLON
|
||||
|
||||
Set device longitude (allows use without GPS).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --setlon -16.8
|
||||
```
|
||||
|
||||
### --debug
|
||||
|
||||
Show API library debug log messages.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --debug --info
|
||||
```
|
||||
|
||||
### --test
|
||||
|
||||
Run stress test against all connected Meshtastic devices.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --test
|
||||
```
|
||||
|
||||
### --ble BLE
|
||||
|
||||
BLE mac address to connect to (BLE is not yet supported for this tool).
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --ble "83:38:92:32:37:48"
|
||||
```
|
||||
|
||||
### --noproto
|
||||
|
||||
Don't start the API, just function as a dumb serial terminal.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --noproto
|
||||
```
|
||||
|
||||
### --version
|
||||
|
||||
Show program's version number and exit.
|
||||
|
||||
**Usage**
|
||||
|
||||
``` shell
|
||||
meshtastic --version
|
||||
```
|
||||
|
||||
## Deprecated Arguments
|
||||
|
||||
### --setchan
|
||||
|
||||
Deprecated - use "--ch-set param value" instead.
|
||||
|
||||
### --set-router
|
||||
|
||||
Deprecated - use "--set is_router true" instead.
|
||||
|
||||
### --unset-router
|
||||
|
||||
Deprecated - use "--set is_router false" instead.
|
||||
@@ -1,17 +0,0 @@
|
||||
# Stream protocol
|
||||
|
||||
Documentation on how out protobufs get encoded when placed onto any stream transport (i.e. TCP or serial, but not UDP or BLE)
|
||||
|
||||
## Wire encoding
|
||||
|
||||
When sending protobuf packets over serial or TCP each packet is preceded by uint32 sent in network byte order (big endian).
|
||||
The upper 16 bits must be 0x94C3. The lower 16 bits are packet length (this encoding gives room to eventually allow quite large packets).
|
||||
|
||||
Implementations validate length against the maximum possible size of a BLE packet (our lowest common denominator) of 512 bytes. If the
|
||||
length provided is larger than that we assume the packet is corrupted and begin again looking for 0x4403 framing.
|
||||
|
||||
The packets flowing towards the device are ToRadio protobufs, the packets flowing from the device are FromRadio protobufs.
|
||||
The 0x94C3 marker can be used as framing to (eventually) resync if packets are corrupted over the wire.
|
||||
|
||||
Note: the 0x94C3 framing was chosen to prevent confusion with the 7 bit ascii character set. It also doesn't collide with any valid utf8 encoding. This makes it a bit easier to start a device outputting regular debug output on its serial port and then only after it has received a valid packet from the PC, turn off unencoded debug printing and switch to this
|
||||
packet encoding.
|
||||
Reference in New Issue
Block a user