diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..aa0afdcf5 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,206 @@ +# Copilot Instructions for Meshtastic Python + +## Project Overview + +This is the Meshtastic Python library and CLI - a Python API for interacting with Meshtastic mesh radio devices. It supports communication via Serial, TCP, and BLE interfaces. + +## Technology Stack + +- **Language**: Python 3.9 - 3.14 +- **Package Manager**: Poetry +- **Testing**: pytest with hypothesis for property-based testing +- **Linting**: pylint +- **Type Checking**: mypy (working toward strict mode) +- **Documentation**: pdoc3 +- **License**: GPL-3.0 + +## Project Structure + +``` +meshtastic/ # Main library package +├── __init__.py # Core interface classes and pub/sub topics +├── __main__.py # CLI entry point +├── mesh_interface.py # Base interface class for all connection types +├── serial_interface.py +├── tcp_interface.py +├── ble_interface.py +├── node.py # Node representation and configuration +├── protobuf/ # Generated Protocol Buffer files (*_pb2.py, *_pb2.pyi) +├── tests/ # Unit and integration tests +├── powermon/ # Power monitoring tools +└── analysis/ # Data analysis tools +examples/ # Usage examples +protobufs/ # Protocol Buffer source definitions +``` + +## Coding Standards + +### Style Guidelines + +- Follow PEP 8 style conventions +- Use type hints for function parameters and return values +- Document public functions and classes with docstrings +- Prefer explicit imports over wildcard imports +- Use `logging` module instead of print statements for debug output + +### Type Annotations + +- Add type hints to all new code +- Use `Optional[T]` for nullable types +- Use `Dict`, `List`, `Tuple` from `typing` module for Python 3.9 compatibility +- Protobuf types are in `meshtastic.protobuf.*_pb2` modules + +### Naming Conventions + +- Classes: `PascalCase` (e.g., `MeshInterface`, `SerialInterface`) +- Functions/methods: `camelCase` for public API (e.g., `sendText`, `sendData`) +- Internal functions: `snake_case` with leading underscore (e.g., `_send_packet`) +- Constants: `UPPER_SNAKE_CASE` (e.g., `BROADCAST_ADDR`, `LOCAL_ADDR`) + +### Error Handling + +- Use custom exception classes when appropriate (e.g., `MeshInterface.MeshInterfaceError`) +- Provide meaningful error messages +- Use `our_exit()` from `meshtastic.util` for CLI exits with error codes + +## Testing + +### Test Organization + +Tests are in `meshtastic/tests/` and use pytest markers: + +- `@pytest.mark.unit` - Fast unit tests (default) +- `@pytest.mark.unitslow` - Slower unit tests +- `@pytest.mark.int` - Integration tests +- `@pytest.mark.smoke1` - Single device smoke tests +- `@pytest.mark.smoke2` - Two device smoke tests +- `@pytest.mark.smokevirt` - Virtual device smoke tests +- `@pytest.mark.examples` - Example validation tests + +### Running Tests + +```bash +# Run unit tests only (default) +make test +# or +pytest -m unit + +# Run all tests +pytest + +# Run with coverage +make cov +``` + +### Writing Tests + +- Use `pytest` fixtures from `conftest.py` +- Use `hypothesis` for property-based testing where appropriate +- Mock external dependencies (serial ports, network connections) +- Test file naming: `test_.py` + +## Pub/Sub Events + +The library uses pypubsub for event handling. Key topics: + +- `meshtastic.connection.established` - Connection successful +- `meshtastic.connection.lost` - Connection lost +- `meshtastic.receive.text(packet)` - Text message received +- `meshtastic.receive.position(packet)` - Position update received +- `meshtastic.receive.data.portnum(packet)` - Data packet by port number +- `meshtastic.node.updated(node)` - Node database changed +- `meshtastic.log.line(line)` - Raw log line from device + +## Protocol Buffers + +- Protobuf definitions are in `protobufs/meshtastic/` +- Generated Python files are in `meshtastic/protobuf/` +- Never edit `*_pb2.py` or `*_pb2.pyi` files directly +- Regenerate with: `make protobufs` or `./bin/regen-protobufs.sh` + +## Common Patterns + +### Creating an Interface + +```python +import meshtastic.serial_interface + +# Auto-detect device +iface = meshtastic.serial_interface.SerialInterface() + +# Specific device +iface = meshtastic.serial_interface.SerialInterface(devPath="/dev/ttyUSB0") + +# Always close when done +iface.close() + +# Or use context manager +with meshtastic.serial_interface.SerialInterface() as iface: + iface.sendText("Hello mesh") +``` + +### Sending Messages + +```python +# Text message (broadcast) +iface.sendText("Hello") + +# Text message to specific node +iface.sendText("Hello", destinationId="!abcd1234") + +# Binary data +iface.sendData(data, portNum=portnums_pb2.PRIVATE_APP) +``` + +### Subscribing to Events + +```python +from pubsub import pub + +def on_receive(packet, interface): + print(f"Received: {packet}") + +pub.subscribe(on_receive, "meshtastic.receive") +``` + +## Development Workflow + +1. Install dependencies: `poetry install --all-extras --with dev` +2. Make changes +3. Run linting: `poetry run pylint meshtastic examples/` +4. Run type checking: `poetry run mypy meshtastic/` +5. Run tests: `poetry run pytest -m unit` +6. Update documentation if needed + +## CLI Development + +The CLI is in `meshtastic/__main__.py`. When adding new CLI commands: + +- Use argparse for argument parsing +- Support `--dest` for specifying target node +- Provide `--help` documentation +- Handle errors gracefully with meaningful messages + +## Dependencies + +### Required +- `pyserial` - Serial port communication +- `protobuf` - Protocol Buffers +- `pypubsub` - Pub/sub messaging +- `bleak` - BLE communication +- `tabulate` - Table formatting +- `pyyaml` - YAML config support +- `requests` - HTTP requests + +### Optional (extras) +- `cli` extra: `pyqrcode`, `print-color`, `dotmap`, `argcomplete` +- `tunnel` extra: `pytap2` +- `analysis` extra: `dash`, `pandas` + +## Important Notes + +- Always test with actual Meshtastic hardware when possible +- Be mindful of radio regulations in your region +- The nodedb (`interface.nodes`) is read-only +- Packet IDs are random 32-bit integers +- Default timeout is 300 seconds for operations diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index c7b937545..b9c75583c 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -1,6 +1,9 @@ name: "Update protobufs" on: workflow_dispatch +permissions: + contents: write + jobs: update-protobufs: runs-on: ubuntu-latest @@ -9,23 +12,34 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: + fetch-depth: 0 submodules: true - - name: Update Submodule + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry run: | - git pull --recurse-submodules + python -m pip install --upgrade pip + python -m pip install poetry + + - name: Update protobuf submodule + run: | + git submodule sync --recursive + git submodule update --init --recursive git submodule update --remote --recursive - name: Download nanopb run: | - wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz + curl -L -o nanopb-0.4.8-linux-x86.tar.gz https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz tar xvzf nanopb-0.4.8-linux-x86.tar.gz mv nanopb-0.4.8-linux-x86 nanopb-0.4.8 - - name: Install poetry (needed by regen-protobufs.sh) + - name: Install Python dependencies run: | - python -m pip install --upgrade pip - pip3 install poetry + poetry install --with dev - name: Re-generate protocol buffers run: | @@ -38,4 +52,9 @@ jobs: git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} git add protobufs git add meshtastic/protobuf - git commit -m "Update protobuf submodule" && git push || echo "No changes to commit" + if [[ -n "$(git status --porcelain)" ]]; then + git commit -m "Update protobufs" + git push + else + echo "No changes to commit" + fi diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 168540025..fa3cf1311 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -37,6 +37,7 @@ except ImportError as e: have_test = False +import meshtastic.ota import meshtastic.util import meshtastic.serial_interface import meshtastic.tcp_interface @@ -60,7 +61,7 @@ have_powermon = False powermon_exception = e meter = None -from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2, mesh_pb2 +from meshtastic.protobuf import admin_pb2, channel_pb2, config_pb2, portnums_pb2, mesh_pb2 from meshtastic.version import get_active_version logger = logging.getLogger(__name__) @@ -158,11 +159,11 @@ def _printSetting(config_type, uni_name, pref_value, repeated): config_values = getattr(config, config_type.name) if not wholeField: pref_value = getattr(config_values, pref.name) - repeated = pref.label == pref.LABEL_REPEATED + repeated = _is_repeated_field(pref) _printSetting(config_type, uni_name, pref_value, repeated) else: for field in config_values.ListFields(): - repeated = field[0].label == field[0].LABEL_REPEATED + repeated = _is_repeated_field(field[0]) _printSetting(config_type, field[0].name, field[1], repeated) else: # Always show whole field for remote node @@ -253,7 +254,7 @@ def setPref(config, comp_name, raw_val) -> bool: return False # repeating fields need to be handled with append, not setattr - if pref.label != pref.LABEL_REPEATED: + if not _is_repeated_field(pref): try: if config_type.message_type is not None: config_values = getattr(config_part, config_type.name) @@ -452,6 +453,41 @@ def onConnected(interface): waitForAckNak = True interface.getNode(args.dest, False, **getNode_kwargs).rebootOTA() + if args.ota_update: + closeNow = True + waitForAckNak = True + + if not isinstance(interface, meshtastic.tcp_interface.TCPInterface): + meshtastic.util.our_exit( + "Error: OTA update currently requires a TCP connection to the node (use --host)." + ) + + ota = meshtastic.ota.ESP32WiFiOTA(args.ota_update, interface.hostname) + + print(f"Triggering OTA update on {interface.hostname}...") + interface.getNode(args.dest, False, **getNode_kwargs).startOTA( + ota_mode=admin_pb2.OTAMode.OTA_WIFI, + ota_file_hash=ota.hash_bytes() + ) + + print("Waiting for device to reboot into OTA mode...") + time.sleep(5) + + retries = 5 + while retries > 0: + try: + ota.update() + break + + except Exception as e: + retries -= 1 + if retries == 0: + meshtastic.util.our_exit(f"\nOTA update failed: {e}") + + time.sleep(2) + + print("\nOTA update completed successfully!") + if args.enter_dfu: closeNow = True waitForAckNak = True @@ -1131,6 +1167,14 @@ def subscribe() -> None: # pub.subscribe(onNode, "meshtastic.node") +def _is_repeated_field(field_desc) -> bool: + """Return True if the protobuf field is repeated. + Protobuf 6.31.0 and later use an is_repeated property, while older versions compare against the label field. + """ + if hasattr(field_desc, "is_repeated"): + return bool(field_desc.is_repeated) + return field_desc.label == field_desc.LABEL_REPEATED + def set_missing_flags_false(config_dict: dict, true_defaults: set[tuple[str, str]]) -> None: """Ensure that missing default=True keys are present in the config_dict and set to False.""" for path in true_defaults: @@ -1904,10 +1948,18 @@ def addRemoteAdminArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPars group.add_argument( "--reboot-ota", - help="Tell the destination node to reboot into factory firmware (ESP32)", + help="Tell the destination node to reboot into factory firmware (ESP32, firmware version <2.7.18)", action="store_true", ) + group.add_argument( + "--ota-update", + help="Perform an OTA update on the local node (ESP32, firmware version >=2.7.18, WiFi/TCP only for now). " + "Specify the path to the firmware file.", + metavar="FIRMWARE_FILE", + action="store", + ) + group.add_argument( "--enter-dfu", help="Tell the destination node to enter DFU mode (NRF52)", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 20e43b9d9..5dfb393b7 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -419,6 +419,7 @@ def sendText( channelIndex: int = 0, portNum: portnums_pb2.PortNum.ValueType = portnums_pb2.PortNum.TEXT_MESSAGE_APP, replyId: Optional[int]=None, + hopLimit: Optional[int]=None, ): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. @@ -436,6 +437,7 @@ def sendText( portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list replyId -- the ID of the message that this packet is a response to + hopLimit {int} -- hop limit to use Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. @@ -449,7 +451,8 @@ def sendText( wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, - replyId=replyId + replyId=replyId, + hopLimit=hopLimit, ) @@ -459,6 +462,7 @@ def sendAlert( destinationId: Union[int, str] = BROADCAST_ADDR, onResponse: Optional[Callable[[dict], Any]] = None, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """Send an alert text to some other node. This is similar to a text message, but carries a higher priority and is capable of generating special notifications @@ -470,6 +474,7 @@ def sendAlert( Keyword Arguments: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) + hopLimit {int} -- hop limit to use Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. @@ -483,7 +488,8 @@ def sendAlert( wantResponse=False, onResponse=onResponse, channelIndex=channelIndex, - priority=mesh_pb2.MeshPacket.Priority.ALERT + priority=mesh_pb2.MeshPacket.Priority.ALERT, + hopLimit=hopLimit, ) def sendMqttClientProxyMessage(self, topic: str, data: bytes): @@ -585,6 +591,7 @@ def sendPosition( wantAck: bool = False, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """ Send a position packet to some other node (normally a broadcast) @@ -621,6 +628,7 @@ def sendPosition( wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForPosition() @@ -673,7 +681,8 @@ def sendTraceRoute( hopLimit=hopLimit, ) # extend timeout based on number of nodes, limit by configured hopLimit - waitFactor = min(len(self.nodes) - 1 if self.nodes else 0, hopLimit) + nodes_based_factor = (len(self.nodes) - 1) if self.nodes else (hopLimit + 1) + waitFactor = max(1, min(nodes_based_factor, hopLimit + 1)) self.waitForTraceRoute(waitFactor) def onResponseTraceRoute(self, p: dict): @@ -726,7 +735,8 @@ def sendTelemetry( destinationId: Union[int, str] = BROADCAST_ADDR, wantResponse: bool = False, channelIndex: int = 0, - telemetryType: str = "device_metrics" + telemetryType: str = "device_metrics", + hopLimit: Optional[int]=None, ): """Send telemetry and optionally ask for a response""" r = telemetry_pb2.Telemetry() @@ -773,6 +783,7 @@ def sendTelemetry( wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForTelemetry() @@ -842,6 +853,7 @@ def sendWaypoint( wantAck: bool = True, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): # pylint: disable=R0913 """ Send a waypoint packet to some other node (normally a broadcast) @@ -882,6 +894,7 @@ def sendWaypoint( wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForWaypoint() @@ -894,6 +907,7 @@ def deleteWaypoint( wantAck: bool = True, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """ Send a waypoint deletion packet to some other node (normally a broadcast) @@ -920,6 +934,7 @@ def deleteWaypoint( wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForWaypoint() @@ -1455,6 +1470,10 @@ def _handleFromRadio(self, fromRadioBytes): self.localNode.moduleConfig.paxcounter.CopyFrom( fromRadio.moduleConfig.paxcounter ) + elif fromRadio.moduleConfig.HasField("traffic_management"): + self.localNode.moduleConfig.traffic_management.CopyFrom( + fromRadio.moduleConfig.traffic_management + ) else: logger.debug("Unexpected FromRadio payload") diff --git a/meshtastic/node.py b/meshtastic/node.py index afb5611ac..66b6312ff 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -170,11 +170,10 @@ def requestConfig(self, configType): p.get_config_request = configType else: - msgIndex = configType.index if configType.containing_type.name == "LocalConfig": - p.get_config_request = msgIndex + p.get_config_request = admin_pb2.AdminMessage.ConfigType.Value(configType.name.upper() + "_CONFIG") else: - p.get_module_config_request = msgIndex + p.get_module_config_request = configType.index self._sendAdmin(p, wantResponse=True, onResponse=onResponse) if onResponse: @@ -245,6 +244,8 @@ def writeConfig(self, config_name): p.set_module_config.ambient_lighting.CopyFrom(self.moduleConfig.ambient_lighting) elif config_name == "paxcounter": p.set_module_config.paxcounter.CopyFrom(self.moduleConfig.paxcounter) + elif config_name == "traffic_management": + p.set_module_config.traffic_management.CopyFrom(self.moduleConfig.traffic_management) else: our_exit(f"Error: No valid config with name {config_name}") @@ -654,7 +655,7 @@ def commitSettingsTransaction(self): return self._sendAdmin(p, onResponse=onResponse) def rebootOTA(self, secs: int = 10): - """Tell the node to reboot into factory firmware.""" + """Tell the node to reboot into factory firmware (firmware < 2.7.18).""" self.ensureSessionKey() p = admin_pb2.AdminMessage() p.reboot_ota_seconds = secs @@ -667,6 +668,22 @@ def rebootOTA(self, secs: int = 10): onResponse = self.onAckNak return self._sendAdmin(p, onResponse=onResponse) + def startOTA( + self, + ota_mode: admin_pb2.OTAMode.ValueType, + ota_file_hash: bytes, + ): + """Tell the node to start OTA mode (firmware >= 2.7.18).""" + if self != self.iface.localNode: + raise ValueError("startOTA only possible in local node") + + self.ensureSessionKey() + p = admin_pb2.AdminMessage() + p.ota_request.reboot_ota_mode = ota_mode + p.ota_request.ota_hash = ota_file_hash + + return self._sendAdmin(p) + def enterDFUMode(self): """Tell the node to enter DFU mode (NRF52).""" self.ensureSessionKey() diff --git a/meshtastic/ota.py b/meshtastic/ota.py new file mode 100644 index 000000000..af9feae42 --- /dev/null +++ b/meshtastic/ota.py @@ -0,0 +1,128 @@ +"""Meshtastic ESP32 Unified OTA +""" +import os +import hashlib +import socket +import logging +from typing import Optional, Callable + + +logger = logging.getLogger(__name__) + + +def _file_sha256(filename: str): + """Calculate SHA256 hash of a file.""" + sha256_hash = hashlib.sha256() + + with open(filename, "rb") as f: + for byte_block in iter(lambda: f.read(4096), b""): + sha256_hash.update(byte_block) + + return sha256_hash + + +class OTAError(Exception): + """Exception for OTA errors.""" + + +class ESP32WiFiOTA: + """ESP32 WiFi Unified OTA updates.""" + + def __init__(self, filename: str, hostname: str, port: int = 3232): + self._filename = filename + self._hostname = hostname + self._port = port + self._socket: Optional[socket.socket] = None + + if not os.path.exists(self._filename): + raise FileNotFoundError(f"File {self._filename} does not exist") + + self._file_hash = _file_sha256(self._filename) + + def _read_line(self) -> str: + """Read a line from the socket.""" + if not self._socket: + raise ConnectionError("Socket not connected") + + line = b"" + while not line.endswith(b"\n"): + char = self._socket.recv(1) + + if not char: + raise ConnectionError("Connection closed while waiting for response") + + line += char + + return line.decode("utf-8").strip() + + def hash_bytes(self) -> bytes: + """Return the hash as bytes.""" + return self._file_hash.digest() + + def hash_hex(self) -> str: + """Return the hash as a hex string.""" + return self._file_hash.hexdigest() + + def update(self, progress_callback: Optional[Callable[[int, int], None]] = None): + """Perform the OTA update.""" + with open(self._filename, "rb") as f: + data = f.read() + size = len(data) + + logger.info(f"Starting OTA update with {self._filename} ({size} bytes, hash {self.hash_hex()})") + + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.settimeout(15) + try: + self._socket.connect((self._hostname, self._port)) + logger.debug(f"Connected to {self._hostname}:{self._port}") + + # Send start command + self._socket.sendall(f"OTA {size} {self.hash_hex()}\n".encode("utf-8")) + + # Wait for OK from the device + while True: + response = self._read_line() + if response == "OK": + break + + if response == "ERASING": + logger.info("Device is erasing flash...") + elif response.startswith("ERR "): + raise OTAError(f"Device reported error: {response}") + else: + logger.warning(f"Unexpected response: {response}") + + # Stream firmware + sent_bytes = 0 + chunk_size = 1024 + while sent_bytes < size: + chunk = data[sent_bytes : sent_bytes + chunk_size] + self._socket.sendall(chunk) + sent_bytes += len(chunk) + + if progress_callback: + progress_callback(sent_bytes, size) + else: + print(f"[{sent_bytes / size * 100:5.1f}%] Sent {sent_bytes} of {size} bytes...", end="\r") + + if not progress_callback: + print() + + # Wait for OK from device + logger.info("Firmware sent, waiting for verification...") + while True: + response = self._read_line() + if response == "OK": + logger.info("OTA update completed successfully!") + break + + if response.startswith("ERR "): + raise OTAError(f"OTA update failed: {response}") + elif response != "ACK": + logger.warning(f"Unexpected final response: {response}") + + finally: + if self._socket: + self._socket.close() + self._socket = None diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index a4fa81e3a..d76061c1f 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xf8\x1b\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x1aS\n\nInputEvent\x12\x12\n\nevent_code\x18\x01 \x01(\r\x12\x0f\n\x07kb_char\x18\x02 \x01(\r\x12\x0f\n\x07touch_x\x18\x03 \x01(\r\x12\x0f\n\x07touch_y\x18\x04 \x01(\r\x1aS\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.OTAMode\x12\x10\n\x08ota_hash\x18\x02 \x01(\x0c\"\xd6\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\x12\x13\n\x0fSECURITY_CONFIG\x10\x07\x12\x15\n\x11SESSIONKEY_CONFIG\x10\x08\x12\x13\n\x0f\x44\x45VICEUI_CONFIG\x10\t\"\xd5\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x12\x18\n\x14STATUSMESSAGE_CONFIG\x10\r\"#\n\x0e\x42\x61\x63kupLocation\x12\t\n\x05\x46LASH\x10\x00\x12\x06\n\x02SD\x10\x01\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"|\n\rSharedContact\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x15\n\rshould_ignore\x18\x03 \x01(\x08\x12\x19\n\x11manually_verified\x18\x04 \x01(\x08\"\xa5\x02\n\x14KeyVerificationAdmin\x12K\n\x0cmessage_type\x18\x01 \x01(\x0e\x32\x35.meshtastic.protobuf.KeyVerificationAdmin.MessageType\x12\x16\n\x0eremote_nodenum\x18\x02 \x01(\r\x12\r\n\x05nonce\x18\x03 \x01(\x04\x12\x1c\n\x0fsecurity_number\x18\x04 \x01(\rH\x00\x88\x01\x01\"g\n\x0bMessageType\x12\x19\n\x15INITIATE_VERIFICATION\x10\x00\x12\x1b\n\x17PROVIDE_SECURITY_NUMBER\x10\x01\x12\r\n\tDO_VERIFY\x10\x02\x12\x11\n\rDO_NOT_VERIFY\x10\x03\x42\x12\n\x10_security_number*7\n\x07OTAMode\x12\x11\n\rNO_REBOOT_OTA\x10\x00\x12\x0b\n\x07OTA_BLE\x10\x01\x12\x0c\n\x08OTA_WIFI\x10\x02\x42\x61\n\x14org.meshtastic.protoB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xd2\x1c\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x12:\n\rsensor_config\x18g \x01(\x0b\x32!.meshtastic.protobuf.SensorConfigH\x00\x1aS\n\nInputEvent\x12\x12\n\nevent_code\x18\x01 \x01(\r\x12\x0f\n\x07kb_char\x18\x02 \x01(\r\x12\x0f\n\x07touch_x\x18\x03 \x01(\r\x12\x0f\n\x07touch_y\x18\x04 \x01(\r\x1aS\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.OTAMode\x12\x10\n\x08ota_hash\x18\x02 \x01(\x0c\"\xd6\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\x12\x13\n\x0fSECURITY_CONFIG\x10\x07\x12\x15\n\x11SESSIONKEY_CONFIG\x10\x08\x12\x13\n\x0f\x44\x45VICEUI_CONFIG\x10\t\"\xf3\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x12\x18\n\x14STATUSMESSAGE_CONFIG\x10\r\x12\x1c\n\x18TRAFFICMANAGEMENT_CONFIG\x10\x0e\"#\n\x0e\x42\x61\x63kupLocation\x12\t\n\x05\x46LASH\x10\x00\x12\x06\n\x02SD\x10\x01\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"|\n\rSharedContact\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x15\n\rshould_ignore\x18\x03 \x01(\x08\x12\x19\n\x11manually_verified\x18\x04 \x01(\x08\"\xa5\x02\n\x14KeyVerificationAdmin\x12K\n\x0cmessage_type\x18\x01 \x01(\x0e\x32\x35.meshtastic.protobuf.KeyVerificationAdmin.MessageType\x12\x16\n\x0eremote_nodenum\x18\x02 \x01(\r\x12\r\n\x05nonce\x18\x03 \x01(\x04\x12\x1c\n\x0fsecurity_number\x18\x04 \x01(\rH\x00\x88\x01\x01\"g\n\x0bMessageType\x12\x19\n\x15INITIATE_VERIFICATION\x10\x00\x12\x1b\n\x17PROVIDE_SECURITY_NUMBER\x10\x01\x12\r\n\tDO_VERIFY\x10\x02\x12\x11\n\rDO_NOT_VERIFY\x10\x03\x42\x12\n\x10_security_number\"\x80\x01\n\x0cSensorConfig\x12\x37\n\x0cscd4x_config\x18\x01 \x01(\x0b\x32!.meshtastic.protobuf.SCD4X_config\x12\x37\n\x0csen5x_config\x18\x02 \x01(\x0b\x32!.meshtastic.protobuf.SEN5X_config\"\xe2\x02\n\x0cSCD4X_config\x12\x14\n\x07set_asc\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12 \n\x13set_target_co2_conc\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0fset_temperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x19\n\x0cset_altitude\x18\x04 \x01(\rH\x03\x88\x01\x01\x12!\n\x14set_ambient_pressure\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rfactory_reset\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x1b\n\x0eset_power_mode\x18\x07 \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_set_ascB\x16\n\x14_set_target_co2_concB\x12\n\x10_set_temperatureB\x0f\n\r_set_altitudeB\x17\n\x15_set_ambient_pressureB\x10\n\x0e_factory_resetB\x11\n\x0f_set_power_mode\"v\n\x0cSEN5X_config\x12\x1c\n\x0fset_temperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11set_one_shot_mode\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x12\n\x10_set_temperatureB\x14\n\x12_set_one_shot_mode*7\n\x07OTAMode\x12\x11\n\rNO_REBOOT_OTA\x10\x00\x12\x0b\n\x07OTA_BLE\x10\x01\x12\x0c\n\x08OTA_WIFI\x10\x02\x42\x61\n\x14org.meshtastic.protoB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -29,28 +29,34 @@ DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._options = None _ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._serialized_options = b'\030\001' - _globals['_OTAMODE']._serialized_start=4487 - _globals['_OTAMODE']._serialized_end=4542 + _globals['_OTAMODE']._serialized_start=5185 + _globals['_OTAMODE']._serialized_end=5240 _globals['_ADMINMESSAGE']._serialized_start=281 - _globals['_ADMINMESSAGE']._serialized_end=3857 - _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_start=3072 - _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_end=3155 - _globals['_ADMINMESSAGE_OTAEVENT']._serialized_start=3157 - _globals['_ADMINMESSAGE_OTAEVENT']._serialized_end=3240 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=3243 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=3457 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=3460 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=3801 - _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_start=3803 - _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_end=3838 - _globals['_HAMPARAMETERS']._serialized_start=3859 - _globals['_HAMPARAMETERS']._serialized_end=3950 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=3952 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=4063 - _globals['_SHAREDCONTACT']._serialized_start=4065 - _globals['_SHAREDCONTACT']._serialized_end=4189 - _globals['_KEYVERIFICATIONADMIN']._serialized_start=4192 - _globals['_KEYVERIFICATIONADMIN']._serialized_end=4485 - _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_start=4362 - _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_end=4465 + _globals['_ADMINMESSAGE']._serialized_end=3947 + _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_start=3132 + _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_end=3215 + _globals['_ADMINMESSAGE_OTAEVENT']._serialized_start=3217 + _globals['_ADMINMESSAGE_OTAEVENT']._serialized_end=3300 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=3303 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=3517 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=3520 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=3891 + _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_start=3893 + _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_end=3928 + _globals['_HAMPARAMETERS']._serialized_start=3949 + _globals['_HAMPARAMETERS']._serialized_end=4040 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=4042 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=4153 + _globals['_SHAREDCONTACT']._serialized_start=4155 + _globals['_SHAREDCONTACT']._serialized_end=4279 + _globals['_KEYVERIFICATIONADMIN']._serialized_start=4282 + _globals['_KEYVERIFICATIONADMIN']._serialized_end=4575 + _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_start=4452 + _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_end=4555 + _globals['_SENSORCONFIG']._serialized_start=4578 + _globals['_SENSORCONFIG']._serialized_end=4706 + _globals['_SCD4X_CONFIG']._serialized_start=4709 + _globals['_SCD4X_CONFIG']._serialized_end=5063 + _globals['_SEN5X_CONFIG']._serialized_start=5065 + _globals['_SEN5X_CONFIG']._serialized_end=5183 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index a93066575..118ef86c7 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -228,6 +228,10 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + TRAFFICMANAGEMENT_CONFIG: AdminMessage._ModuleConfigType.ValueType # 14 + """ + Traffic management module config + """ class ModuleConfigType(_ModuleConfigType, metaclass=_ModuleConfigTypeEnumTypeWrapper): """ @@ -290,6 +294,10 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + TRAFFICMANAGEMENT_CONFIG: AdminMessage.ModuleConfigType.ValueType # 14 + """ + Traffic management module config + """ class _BackupLocation: ValueType = typing.NewType("ValueType", builtins.int) @@ -439,6 +447,7 @@ class AdminMessage(google.protobuf.message.Message): FACTORY_RESET_CONFIG_FIELD_NUMBER: builtins.int NODEDB_RESET_FIELD_NUMBER: builtins.int OTA_REQUEST_FIELD_NUMBER: builtins.int + SENSOR_CONFIG_FIELD_NUMBER: builtins.int session_passkey: builtins.bytes """ The node generates this key and sends it with any get_x_response packets. @@ -720,6 +729,12 @@ class AdminMessage(google.protobuf.message.Message): Tell the node to reset into the OTA Loader """ + @property + def sensor_config(self) -> global___SensorConfig: + """ + Parameters and sensor configuration + """ + def __init__( self, *, @@ -780,10 +795,11 @@ class AdminMessage(google.protobuf.message.Message): factory_reset_config: builtins.int = ..., nodedb_reset: builtins.bool = ..., ota_request: global___AdminMessage.OTAEvent | None = ..., + sensor_config: global___SensorConfig | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "send_input_event", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "toggle_muted_node", "begin_edit_settings", "commit_edit_settings", "add_contact", "key_verification", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset", "ota_request"] | None: ... + def HasField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "sensor_config", b"sensor_config", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "sensor_config", b"sensor_config", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "send_input_event", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "toggle_muted_node", "begin_edit_settings", "commit_edit_settings", "add_contact", "key_verification", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset", "ota_request", "sensor_config"] | None: ... global___AdminMessage = AdminMessage @@ -977,3 +993,130 @@ class KeyVerificationAdmin(google.protobuf.message.Message): def WhichOneof(self, oneof_group: typing.Literal["_security_number", b"_security_number"]) -> typing.Literal["security_number"] | None: ... global___KeyVerificationAdmin = KeyVerificationAdmin + +@typing.final +class SensorConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCD4X_CONFIG_FIELD_NUMBER: builtins.int + SEN5X_CONFIG_FIELD_NUMBER: builtins.int + @property + def scd4x_config(self) -> global___SCD4X_config: + """ + SCD4X CO2 Sensor configuration + """ + + @property + def sen5x_config(self) -> global___SEN5X_config: + """ + SEN5X PM Sensor configuration + """ + + def __init__( + self, + *, + scd4x_config: global___SCD4X_config | None = ..., + sen5x_config: global___SEN5X_config | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["scd4x_config", b"scd4x_config", "sen5x_config", b"sen5x_config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["scd4x_config", b"scd4x_config", "sen5x_config", b"sen5x_config"]) -> None: ... + +global___SensorConfig = SensorConfig + +@typing.final +class SCD4X_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_ASC_FIELD_NUMBER: builtins.int + SET_TARGET_CO2_CONC_FIELD_NUMBER: builtins.int + SET_TEMPERATURE_FIELD_NUMBER: builtins.int + SET_ALTITUDE_FIELD_NUMBER: builtins.int + SET_AMBIENT_PRESSURE_FIELD_NUMBER: builtins.int + FACTORY_RESET_FIELD_NUMBER: builtins.int + SET_POWER_MODE_FIELD_NUMBER: builtins.int + set_asc: builtins.bool + """ + Set Automatic self-calibration enabled + """ + set_target_co2_conc: builtins.int + """ + Recalibration target CO2 concentration in ppm (FRC or ASC) + """ + set_temperature: builtins.float + """ + Reference temperature in degC + """ + set_altitude: builtins.int + """ + Altitude of sensor in meters above sea level. 0 - 3000m (overrides ambient pressure) + """ + set_ambient_pressure: builtins.int + """ + Sensor ambient pressure in Pa. 70000 - 120000 Pa (overrides altitude) + """ + factory_reset: builtins.bool + """ + Perform a factory reset of the sensor + """ + set_power_mode: builtins.bool + """ + Power mode for sensor (true for low power, false for normal) + """ + def __init__( + self, + *, + set_asc: builtins.bool | None = ..., + set_target_co2_conc: builtins.int | None = ..., + set_temperature: builtins.float | None = ..., + set_altitude: builtins.int | None = ..., + set_ambient_pressure: builtins.int | None = ..., + factory_reset: builtins.bool | None = ..., + set_power_mode: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_factory_reset", b"_factory_reset", "_set_altitude", b"_set_altitude", "_set_ambient_pressure", b"_set_ambient_pressure", "_set_asc", b"_set_asc", "_set_power_mode", b"_set_power_mode", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "factory_reset", b"factory_reset", "set_altitude", b"set_altitude", "set_ambient_pressure", b"set_ambient_pressure", "set_asc", b"set_asc", "set_power_mode", b"set_power_mode", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_factory_reset", b"_factory_reset", "_set_altitude", b"_set_altitude", "_set_ambient_pressure", b"_set_ambient_pressure", "_set_asc", b"_set_asc", "_set_power_mode", b"_set_power_mode", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "factory_reset", b"factory_reset", "set_altitude", b"set_altitude", "set_ambient_pressure", b"set_ambient_pressure", "set_asc", b"set_asc", "set_power_mode", b"set_power_mode", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_factory_reset", b"_factory_reset"]) -> typing.Literal["factory_reset"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_altitude", b"_set_altitude"]) -> typing.Literal["set_altitude"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_ambient_pressure", b"_set_ambient_pressure"]) -> typing.Literal["set_ambient_pressure"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_asc", b"_set_asc"]) -> typing.Literal["set_asc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_power_mode", b"_set_power_mode"]) -> typing.Literal["set_power_mode"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_target_co2_conc", b"_set_target_co2_conc"]) -> typing.Literal["set_target_co2_conc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_temperature", b"_set_temperature"]) -> typing.Literal["set_temperature"] | None: ... + +global___SCD4X_config = SCD4X_config + +@typing.final +class SEN5X_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_TEMPERATURE_FIELD_NUMBER: builtins.int + SET_ONE_SHOT_MODE_FIELD_NUMBER: builtins.int + set_temperature: builtins.float + """ + Reference temperature in degC + """ + set_one_shot_mode: builtins.bool + """ + One-shot mode (true for low power - one-shot mode, false for normal - continuous mode) + """ + def __init__( + self, + *, + set_temperature: builtins.float | None = ..., + set_one_shot_mode: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode", "_set_temperature", b"_set_temperature", "set_one_shot_mode", b"set_one_shot_mode", "set_temperature", b"set_temperature"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode", "_set_temperature", b"_set_temperature", "set_one_shot_mode", b"set_one_shot_mode", "set_temperature", b"set_temperature"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode"]) -> typing.Literal["set_one_shot_mode"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_temperature", b"_set_temperature"]) -> typing.Literal["set_temperature"] | None: ... + +global___SEN5X_config = SEN5X_config diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index f709d1da5..5e9c93ecd 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -14,7 +14,7 @@ from meshtastic.protobuf import device_ui_pb2 as meshtastic_dot_protobuf_dot_device__ui__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\"\xf9*\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x91\x07\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x12H\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerMode\"\xd4\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x10\n\x08REPEATER\x10\x04\x1a\x02\x08\x01\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\x12\x0f\n\x0bROUTER_LATE\x10\x0b\x12\x0f\n\x0b\x43LIENT_BASE\x10\x0c\"s\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x12\x08\n\x04NONE\x10\x04\x12\x16\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xf7\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x12\x19\n\x11\x65nabled_protocols\x18\n \x01(\r\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\"4\n\rProtocolFlags\x12\x10\n\x0cNO_BROADCAST\x10\x00\x12\x11\n\rUDP_BROADCAST\x10\x01\x1a\xb6\x08\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12_\n\ngps_format\x18\x02 \x01(\x0e\x32G.meshtastic.protobuf.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x02\x18\x01\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x1d\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\x12\x15\n\ruse_12h_clock\x18\x0c \x01(\x08\x12\x1a\n\x12use_long_node_name\x18\r \x01(\x08\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"f\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\x12\x17\n\x13OLED_SH1107_128_128\x10\x04\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x80\x08\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\x12\x19\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\"\xae\x02\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\x12\n\n\x06PH_433\x10\x13\x12\n\n\x06PH_868\x10\x14\x12\n\n\x06PH_915\x10\x15\x12\x0b\n\x07\x41NZ_433\x10\x16\x12\n\n\x06KZ_433\x10\x17\x12\n\n\x06KZ_863\x10\x18\x12\n\n\x06NP_865\x10\x19\x12\n\n\x06\x42R_902\x10\x1a\"\xbd\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\x11\n\tLONG_SLOW\x10\x01\x1a\x02\x08\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x12\x0e\n\nLONG_TURBO\x10\t\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xb6\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x03(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\"\x99+\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x91\x07\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x12H\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerMode\"\xd4\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x10\n\x08REPEATER\x10\x04\x1a\x02\x08\x01\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\x12\x0f\n\x0bROUTER_LATE\x10\x0b\x12\x0f\n\x0b\x43LIENT_BASE\x10\x0c\"s\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x12\x08\n\x04NONE\x10\x04\x12\x16\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xf7\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x12\x19\n\x11\x65nabled_protocols\x18\n \x01(\r\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\"4\n\rProtocolFlags\x12\x10\n\x0cNO_BROADCAST\x10\x00\x12\x11\n\rUDP_BROADCAST\x10\x01\x1a\xd6\x08\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12_\n\ngps_format\x18\x02 \x01(\x0e\x32G.meshtastic.protobuf.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x02\x18\x01\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x1d\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\x12\x15\n\ruse_12h_clock\x18\x0c \x01(\x08\x12\x1a\n\x12use_long_node_name\x18\r \x01(\x08\x12\x1e\n\x16\x65nable_message_bubbles\x18\x0e \x01(\x08\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"f\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\x12\x17\n\x13OLED_SH1107_128_128\x10\x04\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x80\x08\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\x12\x19\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\"\xae\x02\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\x12\n\n\x06PH_433\x10\x13\x12\n\n\x06PH_868\x10\x14\x12\n\n\x06PH_915\x10\x15\x12\x0b\n\x07\x41NZ_433\x10\x16\x12\n\n\x06KZ_433\x10\x17\x12\n\n\x06KZ_863\x10\x18\x12\n\n\x06NP_865\x10\x19\x12\n\n\x06\x42R_902\x10\x1a\"\xbd\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\x11\n\tLONG_SLOW\x10\x01\x1a\x02\x08\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x12\x0e\n\nLONG_TURBO\x10\t\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xb6\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x03(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -43,7 +43,7 @@ _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._options = None _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001' _globals['_CONFIG']._serialized_start=95 - _globals['_CONFIG']._serialized_end=5592 + _globals['_CONFIG']._serialized_end=5624 _globals['_CONFIG_DEVICECONFIG']._serialized_start=724 _globals['_CONFIG_DEVICECONFIG']._serialized_end=1637 _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1201 @@ -69,29 +69,29 @@ _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_start=3023 _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_end=3075 _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=3078 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=4156 - _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_start=3711 - _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_end=3754 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3756 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3796 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3798 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3900 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3902 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3967 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3970 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=4156 - _globals['_CONFIG_LORACONFIG']._serialized_start=4159 - _globals['_CONFIG_LORACONFIG']._serialized_end=5183 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4689 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4991 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4994 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=5183 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=5186 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=5368 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=5312 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=5368 - _globals['_CONFIG_SECURITYCONFIG']._serialized_start=5371 - _globals['_CONFIG_SECURITYCONFIG']._serialized_end=5553 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=5555 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=5573 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=4188 + _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_start=3743 + _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_end=3786 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3788 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3828 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3830 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3932 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3934 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3999 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=4002 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=4188 + _globals['_CONFIG_LORACONFIG']._serialized_start=4191 + _globals['_CONFIG_LORACONFIG']._serialized_end=5215 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4721 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=5023 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=5026 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=5215 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=5218 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=5400 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=5344 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=5400 + _globals['_CONFIG_SECURITYCONFIG']._serialized_start=5403 + _globals['_CONFIG_SECURITYCONFIG']._serialized_end=5585 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=5587 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=5605 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 47941b47c..50c6f135e 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -1164,6 +1164,7 @@ class Config(google.protobuf.message.Message): COMPASS_ORIENTATION_FIELD_NUMBER: builtins.int USE_12H_CLOCK_FIELD_NUMBER: builtins.int USE_LONG_NODE_NAME_FIELD_NUMBER: builtins.int + ENABLE_MESSAGE_BUBBLES_FIELD_NUMBER: builtins.int screen_on_secs: builtins.int """ Number of seconds the screen stays on after pressing the user button or receiving a message @@ -1222,6 +1223,10 @@ class Config(google.protobuf.message.Message): If false (default), the device will use short names for various display screens. If true, node names will show in long format """ + enable_message_bubbles: builtins.bool + """ + If true, the device will display message bubbles on screen. + """ def __init__( self, *, @@ -1238,8 +1243,9 @@ class Config(google.protobuf.message.Message): compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType = ..., use_12h_clock: builtins.bool = ..., use_long_node_name: builtins.bool = ..., + enable_message_bubbles: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "use_long_node_name", b"use_long_node_name", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... + def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "enable_message_bubbles", b"enable_message_bubbles", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "use_long_node_name", b"use_long_node_name", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... @typing.final class LoRaConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/localonly_pb2.py b/meshtastic/protobuf/localonly_pb2.py index 70d718314..fbe1b7ab6 100644 --- a/meshtastic/protobuf/localonly_pb2.py +++ b/meshtastic/protobuf/localonly_pb2.py @@ -15,7 +15,7 @@ from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xbe\x08\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12L\n\rstatusmessage\x18\x0f \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\x95\t\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12L\n\rstatusmessage\x18\x0f \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfig\x12U\n\x12traffic_management\x18\x10 \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,5 +26,5 @@ _globals['_LOCALCONFIG']._serialized_start=136 _globals['_LOCALCONFIG']._serialized_end=642 _globals['_LOCALMODULECONFIG']._serialized_start=645 - _globals['_LOCALMODULECONFIG']._serialized_end=1731 + _globals['_LOCALMODULECONFIG']._serialized_end=1818 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/localonly_pb2.pyi b/meshtastic/protobuf/localonly_pb2.pyi index 8ed7caee9..32c930ea6 100644 --- a/meshtastic/protobuf/localonly_pb2.pyi +++ b/meshtastic/protobuf/localonly_pb2.pyi @@ -120,6 +120,7 @@ class LocalModuleConfig(google.protobuf.message.Message): DETECTION_SENSOR_FIELD_NUMBER: builtins.int PAXCOUNTER_FIELD_NUMBER: builtins.int STATUSMESSAGE_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int version: builtins.int """ @@ -211,6 +212,12 @@ class LocalModuleConfig(google.protobuf.message.Message): StatusMessage Config """ + @property + def traffic_management(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.TrafficManagementConfig: + """ + The part of the config that is specific to the Traffic Management module + """ + def __init__( self, *, @@ -228,9 +235,10 @@ class LocalModuleConfig(google.protobuf.message.Message): detection_sensor: meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig | None = ..., paxcounter: meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig | None = ..., statusmessage: meshtastic.protobuf.module_config_pb2.ModuleConfig.StatusMessageConfig | None = ..., + traffic_management: meshtastic.protobuf.module_config_pb2.ModuleConfig.TrafficManagementConfig | None = ..., version: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "version", b"version"]) -> None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "traffic_management", b"traffic_management", "version", b"version"]) -> None: ... global___LocalModuleConfig = LocalModuleConfig diff --git a/meshtastic/protobuf/module_config_pb2.py b/meshtastic/protobuf/module_config_pb2.py index dc9f5c8fe..ad5851f78 100644 --- a/meshtastic/protobuf/module_config_pb2.py +++ b/meshtastic/protobuf/module_config_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\"\xb2)\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12N\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\xa0\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12\x63\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32\x43.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig.TriggerType\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xb5\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"\x93\x01\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x12\r\n\tVE_DIRECT\x10\x07\x12\r\n\tMS_CONFIG\x10\x08\x12\x07\n\x03LOG\x10\t\x12\x0b\n\x07LOGTEXT\x10\n\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1aY\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x12\x17\n\x0f\x63lear_on_reboot\x18\x04 \x01(\x08\x1a\x8f\x04\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x12\"\n\x1ahealth_measurement_enabled\x18\x0b \x01(\x08\x12\x1e\n\x16health_update_interval\x18\x0c \x01(\r\x12\x1d\n\x15health_screen_enabled\x18\r \x01(\x08\x12 \n\x18\x64\x65vice_telemetry_enabled\x18\x0e \x01(\x08\x12\"\n\x1a\x61ir_quality_screen_enabled\x18\x0f \x01(\x08\x1a\xf9\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x13\n\x07\x65nabled\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1e\n\x12\x61llow_input_source\x18\n \x01(\tB\x02\x18\x01\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\r\x1a*\n\x13StatusMessageConfig\x12\x13\n\x0bnode_status\x18\x01 \x01(\tB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42h\n\x14org.meshtastic.protoB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\"\xe1-\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12N\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigH\x00\x12W\n\x12traffic_management\x18\x0f \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\xa0\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12\x63\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32\x43.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig.TriggerType\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xd3\x03\n\x17TrafficManagementConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16position_dedup_enabled\x18\x02 \x01(\x08\x12\x1f\n\x17position_precision_bits\x18\x03 \x01(\r\x12\"\n\x1aposition_min_interval_secs\x18\x04 \x01(\r\x12 \n\x18nodeinfo_direct_response\x18\x05 \x01(\x08\x12)\n!nodeinfo_direct_response_max_hops\x18\x06 \x01(\r\x12\x1a\n\x12rate_limit_enabled\x18\x07 \x01(\x08\x12\x1e\n\x16rate_limit_window_secs\x18\x08 \x01(\r\x12\x1e\n\x16rate_limit_max_packets\x18\t \x01(\r\x12\x1c\n\x14\x64rop_unknown_enabled\x18\n \x01(\x08\x12 \n\x18unknown_packet_threshold\x18\x0b \x01(\r\x12\x1d\n\x15\x65xhaust_hop_telemetry\x18\x0c \x01(\x08\x12\x1c\n\x14\x65xhaust_hop_position\x18\r \x01(\x08\x12\x1c\n\x14router_preserve_hops\x18\x0e \x01(\x08\x1a\xb5\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"\x93\x01\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x12\r\n\tVE_DIRECT\x10\x07\x12\r\n\tMS_CONFIG\x10\x08\x12\x07\n\x03LOG\x10\t\x12\x0b\n\x07LOGTEXT\x10\n\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1aY\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x12\x17\n\x0f\x63lear_on_reboot\x18\x04 \x01(\x08\x1a\x8f\x04\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x12\"\n\x1ahealth_measurement_enabled\x18\x0b \x01(\x08\x12\x1e\n\x16health_update_interval\x18\x0c \x01(\r\x12\x1d\n\x15health_screen_enabled\x18\r \x01(\x08\x12 \n\x18\x64\x65vice_telemetry_enabled\x18\x0e \x01(\x08\x12\"\n\x1a\x61ir_quality_screen_enabled\x18\x0f \x01(\x08\x1a\xf9\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x13\n\x07\x65nabled\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1e\n\x12\x61llow_input_source\x18\n \x01(\tB\x02\x18\x01\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\r\x1a*\n\x13StatusMessageConfig\x12\x13\n\x0bnode_status\x18\x01 \x01(\tB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42h\n\x14org.meshtastic.protoB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -25,50 +25,52 @@ _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._serialized_options = b'\030\001' _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._options = None _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._serialized_options = b'\030\001' - _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=5476 - _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=5549 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=6035 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=6108 _globals['_MODULECONFIG']._serialized_start=65 - _globals['_MODULECONFIG']._serialized_end=5363 - _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1160 - _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1473 - _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1475 - _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_end=1585 - _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_start=1588 - _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_end=1727 - _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_start=1729 - _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_end=1819 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_start=1822 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_end=2238 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_start=2102 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_end=2238 - _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_start=2241 - _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_end=2606 - _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_start=2439 - _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_end=2606 - _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2608 - _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=2726 - _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=2729 - _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3422 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=3006 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=3272 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=3275 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3422 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3425 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=3786 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=3789 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=3940 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=3942 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=4031 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=4034 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=4561 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=4564 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=5197 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=5098 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=5197 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=5199 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=5300 - _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_start=5302 - _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_end=5344 - _globals['_REMOTEHARDWAREPIN']._serialized_start=5365 - _globals['_REMOTEHARDWAREPIN']._serialized_end=5474 + _globals['_MODULECONFIG']._serialized_end=5922 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1249 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1562 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1564 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_end=1674 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_start=1677 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_end=1816 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_start=1818 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_end=1908 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_start=1911 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_end=2327 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_start=2191 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_end=2327 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_start=2330 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_end=2695 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_start=2528 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_end=2695 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2697 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=2815 + _globals['_MODULECONFIG_TRAFFICMANAGEMENTCONFIG']._serialized_start=2818 + _globals['_MODULECONFIG_TRAFFICMANAGEMENTCONFIG']._serialized_end=3285 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=3288 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3981 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=3565 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=3831 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=3834 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3981 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3984 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=4345 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=4348 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=4499 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=4501 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=4590 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=4593 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=5120 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=5123 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=5756 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=5657 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=5756 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=5758 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=5859 + _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_start=5861 + _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_end=5903 + _globals['_REMOTEHARDWAREPIN']._serialized_start=5924 + _globals['_REMOTEHARDWAREPIN']._serialized_end=6033 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/module_config_pb2.pyi b/meshtastic/protobuf/module_config_pb2.pyi index 00062b702..878c40e3a 100644 --- a/meshtastic/protobuf/module_config_pb2.pyi +++ b/meshtastic/protobuf/module_config_pb2.pyi @@ -492,6 +492,105 @@ class ModuleConfig(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing.Literal["ble_threshold", b"ble_threshold", "enabled", b"enabled", "paxcounter_update_interval", b"paxcounter_update_interval", "wifi_threshold", b"wifi_threshold"]) -> None: ... + @typing.final + class TrafficManagementConfig(google.protobuf.message.Message): + """ + Config for the Traffic Management module. + Provides packet inspection and traffic shaping to help reduce channel utilization + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + POSITION_DEDUP_ENABLED_FIELD_NUMBER: builtins.int + POSITION_PRECISION_BITS_FIELD_NUMBER: builtins.int + POSITION_MIN_INTERVAL_SECS_FIELD_NUMBER: builtins.int + NODEINFO_DIRECT_RESPONSE_FIELD_NUMBER: builtins.int + NODEINFO_DIRECT_RESPONSE_MAX_HOPS_FIELD_NUMBER: builtins.int + RATE_LIMIT_ENABLED_FIELD_NUMBER: builtins.int + RATE_LIMIT_WINDOW_SECS_FIELD_NUMBER: builtins.int + RATE_LIMIT_MAX_PACKETS_FIELD_NUMBER: builtins.int + DROP_UNKNOWN_ENABLED_FIELD_NUMBER: builtins.int + UNKNOWN_PACKET_THRESHOLD_FIELD_NUMBER: builtins.int + EXHAUST_HOP_TELEMETRY_FIELD_NUMBER: builtins.int + EXHAUST_HOP_POSITION_FIELD_NUMBER: builtins.int + ROUTER_PRESERVE_HOPS_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Master enable for traffic management module + """ + position_dedup_enabled: builtins.bool + """ + Enable position deduplication to drop redundant position broadcasts + """ + position_precision_bits: builtins.int + """ + Number of bits of precision for position deduplication (0-32) + """ + position_min_interval_secs: builtins.int + """ + Minimum interval in seconds between position updates from the same node + """ + nodeinfo_direct_response: builtins.bool + """ + Enable direct response to NodeInfo requests from local cache + """ + nodeinfo_direct_response_max_hops: builtins.int + """ + Minimum hop distance from requestor before responding to NodeInfo requests + """ + rate_limit_enabled: builtins.bool + """ + Enable per-node rate limiting to throttle chatty nodes + """ + rate_limit_window_secs: builtins.int + """ + Time window in seconds for rate limiting calculations + """ + rate_limit_max_packets: builtins.int + """ + Maximum packets allowed per node within the rate limit window + """ + drop_unknown_enabled: builtins.bool + """ + Enable dropping of unknown/undecryptable packets per rate_limit_window_secs + """ + unknown_packet_threshold: builtins.int + """ + Number of unknown packets before dropping from a node + """ + exhaust_hop_telemetry: builtins.bool + """ + Set hop_limit to 0 for relayed telemetry broadcasts (own packets unaffected) + """ + exhaust_hop_position: builtins.bool + """ + Set hop_limit to 0 for relayed position broadcasts (own packets unaffected) + """ + router_preserve_hops: builtins.bool + """ + Preserve hop_limit for router-to-router traffic + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + position_dedup_enabled: builtins.bool = ..., + position_precision_bits: builtins.int = ..., + position_min_interval_secs: builtins.int = ..., + nodeinfo_direct_response: builtins.bool = ..., + nodeinfo_direct_response_max_hops: builtins.int = ..., + rate_limit_enabled: builtins.bool = ..., + rate_limit_window_secs: builtins.int = ..., + rate_limit_max_packets: builtins.int = ..., + drop_unknown_enabled: builtins.bool = ..., + unknown_packet_threshold: builtins.int = ..., + exhaust_hop_telemetry: builtins.bool = ..., + exhaust_hop_position: builtins.bool = ..., + router_preserve_hops: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["drop_unknown_enabled", b"drop_unknown_enabled", "enabled", b"enabled", "exhaust_hop_position", b"exhaust_hop_position", "exhaust_hop_telemetry", b"exhaust_hop_telemetry", "nodeinfo_direct_response", b"nodeinfo_direct_response", "nodeinfo_direct_response_max_hops", b"nodeinfo_direct_response_max_hops", "position_dedup_enabled", b"position_dedup_enabled", "position_min_interval_secs", b"position_min_interval_secs", "position_precision_bits", b"position_precision_bits", "rate_limit_enabled", b"rate_limit_enabled", "rate_limit_max_packets", b"rate_limit_max_packets", "rate_limit_window_secs", b"rate_limit_window_secs", "router_preserve_hops", b"router_preserve_hops", "unknown_packet_threshold", b"unknown_packet_threshold"]) -> None: ... + @typing.final class SerialConfig(google.protobuf.message.Message): """ @@ -1216,6 +1315,7 @@ class ModuleConfig(google.protobuf.message.Message): DETECTION_SENSOR_FIELD_NUMBER: builtins.int PAXCOUNTER_FIELD_NUMBER: builtins.int STATUSMESSAGE_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_FIELD_NUMBER: builtins.int @property def mqtt(self) -> global___ModuleConfig.MQTTConfig: """ @@ -1300,6 +1400,12 @@ class ModuleConfig(google.protobuf.message.Message): TODO: REPLACE """ + @property + def traffic_management(self) -> global___ModuleConfig.TrafficManagementConfig: + """ + Traffic management module config for mesh network optimization + """ + def __init__( self, *, @@ -1317,10 +1423,11 @@ class ModuleConfig(google.protobuf.message.Message): detection_sensor: global___ModuleConfig.DetectionSensorConfig | None = ..., paxcounter: global___ModuleConfig.PaxcounterConfig | None = ..., statusmessage: global___ModuleConfig.StatusMessageConfig | None = ..., + traffic_management: global___ModuleConfig.TrafficManagementConfig | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter", "statusmessage"] | None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter", "statusmessage", "traffic_management"] | None: ... global___ModuleConfig = ModuleConfig diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 5b04c45e3..583215e88 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\x82\x07\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperature\"\xae\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x18\n\x0b\x63h4_voltage\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x18\n\x0b\x63h4_current\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x18\n\x0b\x63h5_voltage\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x18\n\x0b\x63h5_current\x18\n \x01(\x02H\t\x88\x01\x01\x12\x18\n\x0b\x63h6_voltage\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x18\n\x0b\x63h6_current\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x18\n\x0b\x63h7_voltage\x18\r \x01(\x02H\x0c\x88\x01\x01\x12\x18\n\x0b\x63h7_current\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x18\n\x0b\x63h8_voltage\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x18\n\x0b\x63h8_current\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xb1\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tps\"\xff\x02\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x16\n\x0enum_tx_dropped\x18\x0e \x01(\r\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"{\n\rHealthMetrics\x12\x16\n\theart_bpm\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04spO2\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\x91\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\r\n\x05load1\x18\x06 \x01(\r\x12\r\n\x05load5\x18\x07 \x01(\r\x12\x0e\n\x06load15\x18\x08 \x01(\r\x12\x18\n\x0buser_string\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xdd\x03\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x12<\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\".meshtastic.protobuf.HealthMetricsH\x00\x12\x38\n\x0chost_metrics\x18\x08 \x01(\x0b\x32 .meshtastic.protobuf.HostMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xf9\x04\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-Be\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\x82\x07\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperature\"\xae\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x18\n\x0b\x63h4_voltage\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x18\n\x0b\x63h4_current\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x18\n\x0b\x63h5_voltage\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x18\n\x0b\x63h5_current\x18\n \x01(\x02H\t\x88\x01\x01\x12\x18\n\x0b\x63h6_voltage\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x18\n\x0b\x63h6_current\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x18\n\x0b\x63h7_voltage\x18\r \x01(\x02H\x0c\x88\x01\x01\x12\x18\n\x0b\x63h7_current\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x18\n\x0b\x63h8_voltage\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x18\n\x0b\x63h8_current\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xb1\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tps\"\xff\x02\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x16\n\x0enum_tx_dropped\x18\x0e \x01(\r\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"\xe4\x01\n\x16TrafficManagementStats\x12\x19\n\x11packets_inspected\x18\x01 \x01(\r\x12\x1c\n\x14position_dedup_drops\x18\x02 \x01(\r\x12\x1b\n\x13nodeinfo_cache_hits\x18\x03 \x01(\r\x12\x18\n\x10rate_limit_drops\x18\x04 \x01(\r\x12\x1c\n\x14unknown_packet_drops\x18\x05 \x01(\r\x12\x1d\n\x15hop_exhausted_packets\x18\x06 \x01(\r\x12\x1d\n\x15router_hops_preserved\x18\x07 \x01(\r\"{\n\rHealthMetrics\x12\x16\n\theart_bpm\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04spO2\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\x91\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\r\n\x05load1\x18\x06 \x01(\r\x12\r\n\x05load5\x18\x07 \x01(\r\x12\x0e\n\x06load15\x18\x08 \x01(\r\x12\x18\n\x0buser_string\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xae\x04\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x12<\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\".meshtastic.protobuf.HealthMetricsH\x00\x12\x38\n\x0chost_metrics\x18\x08 \x01(\x0b\x32 .meshtastic.protobuf.HostMetricsH\x00\x12O\n\x18traffic_management_stats\x18\t \x01(\x0b\x32+.meshtastic.protobuf.TrafficManagementStatsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02\"\xf0\x01\n\nSEN5XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array*\x9c\x05\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-\x12\x0b\n\x07HDC1080\x10.\x12\t\n\x05SHT21\x10/\x12\t\n\x05STC31\x10\x30\x42\x65\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,8 +21,8 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=4432 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=5065 + _globals['_TELEMETRYSENSORTYPE']._serialized_start=4987 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=5655 _globals['_DEVICEMETRICS']._serialized_start=61 _globals['_DEVICEMETRICS']._serialized_end=304 _globals['_ENVIRONMENTMETRICS']._serialized_start=307 @@ -33,12 +33,16 @@ _globals['_AIRQUALITYMETRICS']._serialized_end=3098 _globals['_LOCALSTATS']._serialized_start=3101 _globals['_LOCALSTATS']._serialized_end=3484 - _globals['_HEALTHMETRICS']._serialized_start=3486 - _globals['_HEALTHMETRICS']._serialized_end=3609 - _globals['_HOSTMETRICS']._serialized_start=3612 - _globals['_HOSTMETRICS']._serialized_end=3885 - _globals['_TELEMETRY']._serialized_start=3888 - _globals['_TELEMETRY']._serialized_end=4365 - _globals['_NAU7802CONFIG']._serialized_start=4367 - _globals['_NAU7802CONFIG']._serialized_end=4429 + _globals['_TRAFFICMANAGEMENTSTATS']._serialized_start=3487 + _globals['_TRAFFICMANAGEMENTSTATS']._serialized_end=3715 + _globals['_HEALTHMETRICS']._serialized_start=3717 + _globals['_HEALTHMETRICS']._serialized_end=3840 + _globals['_HOSTMETRICS']._serialized_start=3843 + _globals['_HOSTMETRICS']._serialized_end=4116 + _globals['_TELEMETRY']._serialized_start=4119 + _globals['_TELEMETRY']._serialized_end=4677 + _globals['_NAU7802CONFIG']._serialized_start=4679 + _globals['_NAU7802CONFIG']._serialized_end=4741 + _globals['_SEN5XSTATE']._serialized_start=4744 + _globals['_SEN5XSTATE']._serialized_end=4984 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index 23c102597..322fdbfd6 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -207,6 +207,18 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ BH1750 light sensor """ + HDC1080: _TelemetrySensorType.ValueType # 46 + """ + HDC1080 Temperature and Humidity Sensor + """ + SHT21: _TelemetrySensorType.ValueType # 47 + """ + STH21 Temperature and R. Humidity sensor + """ + STC31: _TelemetrySensorType.ValueType # 48 + """ + Sensirion STC31 CO2 sensor + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -397,6 +409,18 @@ BH1750: TelemetrySensorType.ValueType # 45 """ BH1750 light sensor """ +HDC1080: TelemetrySensorType.ValueType # 46 +""" +HDC1080 Temperature and Humidity Sensor +""" +SHT21: TelemetrySensorType.ValueType # 47 +""" +STH21 Temperature and R. Humidity sensor +""" +STC31: TelemetrySensorType.ValueType # 48 +""" +Sensirion STC31 CO2 sensor +""" global___TelemetrySensorType = TelemetrySensorType @typing.final @@ -1121,6 +1145,64 @@ class LocalStats(google.protobuf.message.Message): global___LocalStats = LocalStats +@typing.final +class TrafficManagementStats(google.protobuf.message.Message): + """ + Traffic management statistics for mesh network optimization + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PACKETS_INSPECTED_FIELD_NUMBER: builtins.int + POSITION_DEDUP_DROPS_FIELD_NUMBER: builtins.int + NODEINFO_CACHE_HITS_FIELD_NUMBER: builtins.int + RATE_LIMIT_DROPS_FIELD_NUMBER: builtins.int + UNKNOWN_PACKET_DROPS_FIELD_NUMBER: builtins.int + HOP_EXHAUSTED_PACKETS_FIELD_NUMBER: builtins.int + ROUTER_HOPS_PRESERVED_FIELD_NUMBER: builtins.int + packets_inspected: builtins.int + """ + Total number of packets inspected by traffic management + """ + position_dedup_drops: builtins.int + """ + Number of position packets dropped due to deduplication + """ + nodeinfo_cache_hits: builtins.int + """ + Number of NodeInfo requests answered from cache + """ + rate_limit_drops: builtins.int + """ + Number of packets dropped due to rate limiting + """ + unknown_packet_drops: builtins.int + """ + Number of unknown/undecryptable packets dropped + """ + hop_exhausted_packets: builtins.int + """ + Number of packets with hop_limit exhausted for local-only broadcast + """ + router_hops_preserved: builtins.int + """ + Number of times router hop preservation was applied + """ + def __init__( + self, + *, + packets_inspected: builtins.int = ..., + position_dedup_drops: builtins.int = ..., + nodeinfo_cache_hits: builtins.int = ..., + rate_limit_drops: builtins.int = ..., + unknown_packet_drops: builtins.int = ..., + hop_exhausted_packets: builtins.int = ..., + router_hops_preserved: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["hop_exhausted_packets", b"hop_exhausted_packets", "nodeinfo_cache_hits", b"nodeinfo_cache_hits", "packets_inspected", b"packets_inspected", "position_dedup_drops", b"position_dedup_drops", "rate_limit_drops", b"rate_limit_drops", "router_hops_preserved", b"router_hops_preserved", "unknown_packet_drops", b"unknown_packet_drops"]) -> None: ... + +global___TrafficManagementStats = TrafficManagementStats + @typing.final class HealthMetrics(google.protobuf.message.Message): """ @@ -1256,6 +1338,7 @@ class Telemetry(google.protobuf.message.Message): LOCAL_STATS_FIELD_NUMBER: builtins.int HEALTH_METRICS_FIELD_NUMBER: builtins.int HOST_METRICS_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_STATS_FIELD_NUMBER: builtins.int time: builtins.int """ Seconds since 1970 - or 0 for unknown/unset @@ -1302,6 +1385,12 @@ class Telemetry(google.protobuf.message.Message): Linux host metrics """ + @property + def traffic_management_stats(self) -> global___TrafficManagementStats: + """ + Traffic management statistics + """ + def __init__( self, *, @@ -1313,10 +1402,11 @@ class Telemetry(google.protobuf.message.Message): local_stats: global___LocalStats | None = ..., health_metrics: global___HealthMetrics | None = ..., host_metrics: global___HostMetrics | None = ..., + traffic_management_stats: global___TrafficManagementStats | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "variant", b"variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "variant", b"variant"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics", "host_metrics"] | None: ... + def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "traffic_management_stats", b"traffic_management_stats", "variant", b"variant"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "traffic_management_stats", b"traffic_management_stats", "variant", b"variant"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics", "host_metrics", "traffic_management_stats"] | None: ... global___Telemetry = Telemetry @@ -1347,3 +1437,62 @@ class Nau7802Config(google.protobuf.message.Message): def ClearField(self, field_name: typing.Literal["calibrationFactor", b"calibrationFactor", "zeroOffset", b"zeroOffset"]) -> None: ... global___Nau7802Config = Nau7802Config + +@typing.final +class SEN5XState(google.protobuf.message.Message): + """ + SEN5X State, for saving to flash + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LAST_CLEANING_TIME_FIELD_NUMBER: builtins.int + LAST_CLEANING_VALID_FIELD_NUMBER: builtins.int + ONE_SHOT_MODE_FIELD_NUMBER: builtins.int + VOC_STATE_TIME_FIELD_NUMBER: builtins.int + VOC_STATE_VALID_FIELD_NUMBER: builtins.int + VOC_STATE_ARRAY_FIELD_NUMBER: builtins.int + last_cleaning_time: builtins.int + """ + Last cleaning time for SEN5X + """ + last_cleaning_valid: builtins.bool + """ + Last cleaning time for SEN5X - valid flag + """ + one_shot_mode: builtins.bool + """ + Config flag for one-shot mode (see admin.proto) + """ + voc_state_time: builtins.int + """ + Last VOC state time for SEN55 + """ + voc_state_valid: builtins.bool + """ + Last VOC state validity flag for SEN55 + """ + voc_state_array: builtins.int + """ + VOC state array (8x uint8t) for SEN55 + """ + def __init__( + self, + *, + last_cleaning_time: builtins.int = ..., + last_cleaning_valid: builtins.bool = ..., + one_shot_mode: builtins.bool = ..., + voc_state_time: builtins.int | None = ..., + voc_state_valid: builtins.bool | None = ..., + voc_state_array: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_voc_state_array", b"_voc_state_array", "_voc_state_time", b"_voc_state_time", "_voc_state_valid", b"_voc_state_valid", "voc_state_array", b"voc_state_array", "voc_state_time", b"voc_state_time", "voc_state_valid", b"voc_state_valid"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_voc_state_array", b"_voc_state_array", "_voc_state_time", b"_voc_state_time", "_voc_state_valid", b"_voc_state_valid", "last_cleaning_time", b"last_cleaning_time", "last_cleaning_valid", b"last_cleaning_valid", "one_shot_mode", b"one_shot_mode", "voc_state_array", b"voc_state_array", "voc_state_time", b"voc_state_time", "voc_state_valid", b"voc_state_valid"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_array", b"_voc_state_array"]) -> typing.Literal["voc_state_array"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_time", b"_voc_state_time"]) -> typing.Literal["voc_state_time"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_valid", b"_voc_state_valid"]) -> typing.Literal["voc_state_valid"] | None: ... + +global___SEN5XState = SEN5XState diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 251de98fe..048614e5d 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -6,6 +6,7 @@ import platform import re import sys +import tempfile from unittest.mock import mock_open, MagicMock, patch import pytest @@ -2900,3 +2901,68 @@ def test_main_set_ham_empty_string(capsys): out, _ = capsys.readouterr() assert "ERROR: Ham radio callsign cannot be empty or contain only whitespace characters" in out assert excinfo.value.code == 1 + + +# OTA-related tests +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_ota_update_file_not_found(capsys): + """Test --ota-update with non-existent file""" + sys.argv = [ + "", + "--ota-update", + "/nonexistent/firmware.bin", + "--host", + "192.168.1.100", + ] + mt_config.args = sys.argv + + with pytest.raises(SystemExit) as pytest_wrapped_e: + main() + + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +@patch("meshtastic.ota.ESP32WiFiOTA") +@patch("meshtastic.__main__.meshtastic.util.our_exit") +def test_main_ota_update_retries(mock_our_exit, mock_ota_class, capsys): + """Test --ota-update retries on failure""" + # Create a temporary firmware file + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + firmware_file = f.name + + try: + sys.argv = ["", "--ota-update", firmware_file, "--host", "192.168.1.100"] + mt_config.args = sys.argv + + # Mock the OTA class to fail all 5 retries + mock_ota = MagicMock() + mock_ota_class.return_value = mock_ota + mock_ota.hash_bytes.return_value = b"\x00" * 32 + mock_ota.hash_hex.return_value = "a" * 64 + mock_ota.update.side_effect = Exception("Connection failed") + + # Mock isinstance to return True + with patch("meshtastic.__main__.isinstance", return_value=True): + with patch("meshtastic.tcp_interface.TCPInterface") as mock_tcp: + mock_iface = MagicMock() + mock_iface.hostname = "192.168.1.100" + mock_iface.localNode = MagicMock(autospec=Node) + mock_tcp.return_value = mock_iface + + with patch("time.sleep"): + main() + + # Should have exhausted all retries and called our_exit + # Note: our_exit might be called twice - once for TCP check, once for failure + assert mock_our_exit.call_count >= 1 + # Check the last call was for OTA failure + last_call_args = mock_our_exit.call_args[0][0] + assert "OTA update failed" in last_call_args + + finally: + os.unlink(firmware_file) diff --git a/meshtastic/tests/test_mesh_interface_traffic_management.py b/meshtastic/tests/test_mesh_interface_traffic_management.py new file mode 100644 index 000000000..f1aa4f9bb --- /dev/null +++ b/meshtastic/tests/test_mesh_interface_traffic_management.py @@ -0,0 +1,22 @@ +"""Meshtastic unit tests for traffic management handling in mesh_interface.py.""" + +import pytest + +from ..mesh_interface import MeshInterface +from ..protobuf import mesh_pb2 + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_handleFromRadio_with_traffic_management_module_config(): + """Test _handleFromRadio with moduleConfig.traffic_management.""" + iface = MeshInterface(noProto=True) + from_radio = mesh_pb2.FromRadio() + from_radio.moduleConfig.traffic_management.enabled = True + from_radio.moduleConfig.traffic_management.rate_limit_enabled = True + + iface._handleFromRadio(from_radio.SerializeToString()) + + assert iface.localNode.moduleConfig.traffic_management.enabled is True + assert iface.localNode.moduleConfig.traffic_management.rate_limit_enabled is True + iface.close() diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index c5cb6b3fa..986c1783c 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -1,4 +1,5 @@ """Meshtastic unit tests for node.py""" +# pylint: disable=C0302 import logging import re @@ -794,6 +795,30 @@ def test_writeConfig_with_no_radioConfig(capsys): assert err == "" +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_writeConfig_traffic_management(): + """Test writeConfig with traffic_management module config.""" + iface = MagicMock(autospec=SerialInterface) + anode = Node(iface, 123, noProto=True) + anode.moduleConfig.traffic_management.enabled = True + anode.moduleConfig.traffic_management.rate_limit_enabled = True + + sent_admin = [] + + def capture_send(p, *args, **kwargs): # pylint: disable=W0613 + sent_admin.append(p) + + with patch.object(anode, "_sendAdmin", side_effect=capture_send): + anode.writeConfig("traffic_management") + + assert len(sent_admin) == 1 + assert sent_admin[0].HasField("set_module_config") + assert sent_admin[0].set_module_config.HasField("traffic_management") + assert sent_admin[0].set_module_config.traffic_management.enabled is True + assert sent_admin[0].set_module_config.traffic_management.rate_limit_enabled is True + + # TODO # @pytest.mark.unit # def test_writeConfig(caplog): @@ -1550,6 +1575,41 @@ def test_setOwner_valid_names(caplog): assert re.search(r'p.set_owner.short_name:VN:', caplog.text, re.MULTILINE) +@pytest.mark.unit +def test_start_ota_local_node(): + """Test startOTA on local node""" + iface = MagicMock(autospec=MeshInterface) + anode = Node(iface, 1234567890, noProto=True) + # Set up as local node + iface.localNode = anode + + amesg = admin_pb2.AdminMessage() + with patch("meshtastic.admin_pb2.AdminMessage", return_value=amesg): + with patch.object(anode, "_sendAdmin") as mock_send_admin: + test_hash = b"\x01\x02\x03" * 8 # 24 bytes hash + anode.startOTA(ota_mode=admin_pb2.OTAMode.OTA_WIFI, ota_file_hash=test_hash) + + # Verify the OTA request was set correctly + assert amesg.ota_request.reboot_ota_mode == admin_pb2.OTAMode.OTA_WIFI + assert amesg.ota_request.ota_hash == test_hash + mock_send_admin.assert_called_once_with(amesg) + + +@pytest.mark.unit +def test_start_ota_remote_node_raises_error(): + """Test startOTA on remote node raises ValueError""" + iface = MagicMock(autospec=MeshInterface) + local_node = Node(iface, 1234567890, noProto=True) + remote_node = Node(iface, 9876543210, noProto=True) + iface.localNode = local_node + + test_hash = b"\x01\x02\x03" * 8 + with pytest.raises(ValueError, match="startOTA only possible in local node"): + remote_node.startOTA( + ota_mode=admin_pb2.OTAMode.OTA_WIFI, ota_file_hash=test_hash + ) + + # TODO # @pytest.mark.unitslow # def test_waitForConfig(): diff --git a/meshtastic/tests/test_ota.py b/meshtastic/tests/test_ota.py new file mode 100644 index 000000000..870336122 --- /dev/null +++ b/meshtastic/tests/test_ota.py @@ -0,0 +1,455 @@ +"""Meshtastic unit tests for ota.py""" + +import hashlib +import logging +import os +import socket +import tempfile +from unittest.mock import MagicMock, patch + +import pytest + +from meshtastic.ota import ( + _file_sha256, + ESP32WiFiOTA, + OTAError, +) + + +@pytest.mark.unit +def test_file_sha256(): + """Test _file_sha256 calculates correct hash""" + # Create a temporary file with known content + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"Hello, World!" + f.write(test_data) + temp_file = f.name + + try: + result = _file_sha256(temp_file) + expected_hash = hashlib.sha256(test_data).hexdigest() + assert result.hexdigest() == expected_hash + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_file_sha256_large_file(): + """Test _file_sha256 handles files larger than chunk size""" + # Create a temporary file with more than 4096 bytes + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 8192 # More than 4096 bytes + f.write(test_data) + temp_file = f.name + + try: + result = _file_sha256(temp_file) + expected_hash = hashlib.sha256(test_data).hexdigest() + assert result.hexdigest() == expected_hash + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_file_not_found(): + """Test ESP32WiFiOTA raises FileNotFoundError for non-existent file""" + with pytest.raises(FileNotFoundError, match="does not exist"): + ESP32WiFiOTA("/nonexistent/firmware.bin", "192.168.1.1") + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_success(): + """Test ESP32WiFiOTA initializes correctly with valid file""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1", 3232) + assert ota._filename == temp_file + assert ota._hostname == "192.168.1.1" + assert ota._port == 3232 + assert ota._socket is None + # Verify hash is calculated + assert ota._file_hash is not None + assert len(ota.hash_hex()) == 64 # SHA256 hex is 64 chars + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_default_port(): + """Test ESP32WiFiOTA uses default port 3232""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + assert ota._port == 3232 + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_hash_bytes(): + """Test hash_bytes returns correct bytes""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"firmware data" + f.write(test_data) + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + hash_bytes = ota.hash_bytes() + expected_bytes = hashlib.sha256(test_data).digest() + assert hash_bytes == expected_bytes + assert len(hash_bytes) == 32 # SHA256 is 32 bytes + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_hash_hex(): + """Test hash_hex returns correct hex string""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"firmware data" + f.write(test_data) + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + hash_hex = ota.hash_hex() + expected_hex = hashlib.sha256(test_data).hexdigest() + assert hash_hex == expected_hex + assert len(hash_hex) == 64 # SHA256 hex is 64 chars + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_not_connected(): + """Test _read_line raises ConnectionError when not connected""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + with pytest.raises(ConnectionError, match="Socket not connected"): + ota._read_line() + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_connection_closed(): + """Test _read_line raises ConnectionError when connection closed""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + mock_socket = MagicMock() + # Simulate connection closed + mock_socket.recv.return_value = b"" + ota._socket = mock_socket + + with pytest.raises(ConnectionError, match="Connection closed"): + ota._read_line() + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_success(): + """Test _read_line successfully reads a line""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + mock_socket = MagicMock() + # Simulate receiving "OK\n" + mock_socket.recv.side_effect = [b"O", b"K", b"\n"] + ota._socket = mock_socket + + result = ota._read_line() + assert result == "OK" + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_success(mock_socket_class): + """Test update() with successful OTA""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 1024 # 1KB of data + f.write(test_data) + temp_file = f.name + + try: + # Setup mock socket + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Mock _read_line to return appropriate responses + # First call: ERASING, Second call: OK (ready), Third call: OK (complete) + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "ERASING", # Device is erasing flash + "OK", # Device ready for firmware + "OK", # Device finished successfully + ] + + ota.update() + + # Verify socket was created and connected + mock_socket_class.assert_called_once_with( + socket.AF_INET, socket.SOCK_STREAM + ) + mock_socket.settimeout.assert_called_once_with(15) + mock_socket.connect.assert_called_once_with(("192.168.1.1", 3232)) + + # Verify start command was sent + start_cmd = f"OTA {len(test_data)} {ota.hash_hex()}\n".encode("utf-8") + mock_socket.sendall.assert_any_call(start_cmd) + + # Verify firmware was sent (at least one chunk) + assert mock_socket.sendall.call_count >= 2 + + # Verify socket was closed + mock_socket.close.assert_called_once() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_with_progress_callback(mock_socket_class): + """Test update() with progress callback""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 1024 # 1KB of data + f.write(test_data) + temp_file = f.name + + try: + # Setup mock socket + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Track progress callback calls + progress_calls = [] + + def progress_callback(sent, total): + progress_calls.append((sent, total)) + + # Mock _read_line + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "OK", # Device finished + ] + + ota.update(progress_callback=progress_callback) + + # Verify progress callback was called + assert len(progress_calls) > 0 + # First call should show some progress + assert progress_calls[0][0] > 0 + # Total should be the firmware size + assert progress_calls[0][1] == len(test_data) + # Last call should show all bytes sent + assert progress_calls[-1][0] == len(test_data) + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_device_error_on_start(mock_socket_class): + """Test update() raises OTAError when device reports error during start""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.return_value = "ERR BAD_HASH" + + with pytest.raises(OTAError, match="Device reported error"): + ota.update() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_device_error_on_finish(mock_socket_class): + """Test update() raises OTAError when device reports error after firmware sent""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "ERR FLASH_ERR", # Error after firmware sent + ] + + with pytest.raises(OTAError, match="OTA update failed"): + ota.update() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_socket_cleanup_on_error(mock_socket_class): + """Test that socket is properly cleaned up on error""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Simulate connection error + mock_socket.connect.side_effect = ConnectionRefusedError("Connection refused") + + with pytest.raises(ConnectionRefusedError): + ota.update() + + # Verify socket was closed even on error + mock_socket.close.assert_called_once() + assert ota._socket is None + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_large_firmware(mock_socket_class): + """Test update() correctly chunks large firmware files""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + # Create a file larger than chunk_size (1024) + test_data = b"B" * 3000 + f.write(test_data) + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "OK", # Device finished + ] + + ota.update() + + # Verify that all data was sent in chunks + # 3000 bytes should be sent in ~3 chunks of 1024 bytes + sendall_calls = [ + call + for call in mock_socket.sendall.call_args_list + if call[0][0] + != f"OTA {len(test_data)} {ota.hash_hex()}\n".encode("utf-8") + ] + # Calculate total data sent (excluding the start command) + total_sent = sum(len(call[0][0]) for call in sendall_calls) + assert total_sent == len(test_data) + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_unexpected_response_warning(mock_socket_class, caplog): + """Test update() logs warning on unexpected response during startup""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "UNKNOWN", # Unexpected response + "OK", # Then proceed + "OK", # Device finished + ] + + with caplog.at_level(logging.WARNING): + ota.update() + + # Check that warning was logged for unexpected response + assert "Unexpected response" in caplog.text + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_unexpected_final_response(mock_socket_class, caplog): + """Test update() logs warning on unexpected final response after firmware upload""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready for firmware + "UNKNOWN", # Unexpected final response (not OK, not ERR, not ACK) + "OK", # Then succeed + ] + + with caplog.at_level(logging.WARNING): + ota.update() + + # Check that warning was logged for unexpected final response + assert "Unexpected final response" in caplog.text + + finally: + os.unlink(temp_file) diff --git a/protobufs b/protobufs index 77c8329a5..e1a6b3a86 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 77c8329a59a9c96a61c447b5d5f1a52ca583e4f2 +Subproject commit e1a6b3a868d735da72cd6c94c574d655129d390a diff --git a/pyproject.toml b/pyproject.toml index d195fef80..9f6cfae6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.7.7" +version = "2.7.8" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only"