mirror of
https://github.com/meshtastic/python.git
synced 2026-02-17 03:11:26 -05:00
5.9 KiB
5.9 KiB
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
loggingmodule 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,Tuplefromtypingmodule for Python 3.9 compatibility - Protobuf types are in
meshtastic.protobuf.*_pb2modules
Naming Conventions
- Classes:
PascalCase(e.g.,MeshInterface,SerialInterface) - Functions/methods:
camelCasefor public API (e.g.,sendText,sendData) - Internal functions:
snake_casewith 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()frommeshtastic.utilfor 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
# Run unit tests only (default)
make test
# or
pytest -m unit
# Run all tests
pytest
# Run with coverage
make cov
Writing Tests
- Use
pytestfixtures fromconftest.py - Use
hypothesisfor property-based testing where appropriate - Mock external dependencies (serial ports, network connections)
- Test file naming:
test_<module_name>.py
Pub/Sub Events
The library uses pypubsub for event handling. Key topics:
meshtastic.connection.established- Connection successfulmeshtastic.connection.lost- Connection lostmeshtastic.receive.text(packet)- Text message receivedmeshtastic.receive.position(packet)- Position update receivedmeshtastic.receive.data.portnum(packet)- Data packet by port numbermeshtastic.node.updated(node)- Node database changedmeshtastic.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.pyor*_pb2.pyifiles directly - Regenerate with:
make protobufsor./bin/regen-protobufs.sh
Common Patterns
Creating an Interface
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
# 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
from pubsub import pub
def on_receive(packet, interface):
print(f"Received: {packet}")
pub.subscribe(on_receive, "meshtastic.receive")
Development Workflow
- Install dependencies:
poetry install --all-extras --with dev - Make changes
- Run linting:
poetry run pylint meshtastic examples/ - Run type checking:
poetry run mypy meshtastic/ - Run tests:
poetry run pytest -m unit - Update documentation if needed
CLI Development
The CLI is in meshtastic/__main__.py. When adding new CLI commands:
- Use argparse for argument parsing
- Support
--destfor specifying target node - Provide
--helpdocumentation - Handle errors gracefully with meaningful messages
Dependencies
Required
pyserial- Serial port communicationprotobuf- Protocol Bufferspypubsub- Pub/sub messagingbleak- BLE communicationtabulate- Table formattingpyyaml- YAML config supportrequests- HTTP requests
Optional (extras)
cliextra:pyqrcode,print-color,dotmap,argcompletetunnelextra:pytap2analysisextra: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