Skip to content

Commit d0ccb1a

Browse files
committed
Update protobufs GH action
1 parent cdf893e commit d0ccb1a

File tree

2 files changed

+232
-7
lines changed

2 files changed

+232
-7
lines changed

.github/copilot-instructions.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# Copilot Instructions for Meshtastic Python
2+
3+
## Project Overview
4+
5+
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.
6+
7+
## Technology Stack
8+
9+
- **Language**: Python 3.9 - 3.14
10+
- **Package Manager**: Poetry
11+
- **Testing**: pytest with hypothesis for property-based testing
12+
- **Linting**: pylint
13+
- **Type Checking**: mypy (working toward strict mode)
14+
- **Documentation**: pdoc3
15+
- **License**: GPL-3.0
16+
17+
## Project Structure
18+
19+
```
20+
meshtastic/ # Main library package
21+
├── __init__.py # Core interface classes and pub/sub topics
22+
├── __main__.py # CLI entry point
23+
├── mesh_interface.py # Base interface class for all connection types
24+
├── serial_interface.py
25+
├── tcp_interface.py
26+
├── ble_interface.py
27+
├── node.py # Node representation and configuration
28+
├── protobuf/ # Generated Protocol Buffer files (*_pb2.py, *_pb2.pyi)
29+
├── tests/ # Unit and integration tests
30+
├── powermon/ # Power monitoring tools
31+
└── analysis/ # Data analysis tools
32+
examples/ # Usage examples
33+
protobufs/ # Protocol Buffer source definitions
34+
```
35+
36+
## Coding Standards
37+
38+
### Style Guidelines
39+
40+
- Follow PEP 8 style conventions
41+
- Use type hints for function parameters and return values
42+
- Document public functions and classes with docstrings
43+
- Prefer explicit imports over wildcard imports
44+
- Use `logging` module instead of print statements for debug output
45+
46+
### Type Annotations
47+
48+
- Add type hints to all new code
49+
- Use `Optional[T]` for nullable types
50+
- Use `Dict`, `List`, `Tuple` from `typing` module for Python 3.9 compatibility
51+
- Protobuf types are in `meshtastic.protobuf.*_pb2` modules
52+
53+
### Naming Conventions
54+
55+
- Classes: `PascalCase` (e.g., `MeshInterface`, `SerialInterface`)
56+
- Functions/methods: `camelCase` for public API (e.g., `sendText`, `sendData`)
57+
- Internal functions: `snake_case` with leading underscore (e.g., `_send_packet`)
58+
- Constants: `UPPER_SNAKE_CASE` (e.g., `BROADCAST_ADDR`, `LOCAL_ADDR`)
59+
60+
### Error Handling
61+
62+
- Use custom exception classes when appropriate (e.g., `MeshInterface.MeshInterfaceError`)
63+
- Provide meaningful error messages
64+
- Use `our_exit()` from `meshtastic.util` for CLI exits with error codes
65+
66+
## Testing
67+
68+
### Test Organization
69+
70+
Tests are in `meshtastic/tests/` and use pytest markers:
71+
72+
- `@pytest.mark.unit` - Fast unit tests (default)
73+
- `@pytest.mark.unitslow` - Slower unit tests
74+
- `@pytest.mark.int` - Integration tests
75+
- `@pytest.mark.smoke1` - Single device smoke tests
76+
- `@pytest.mark.smoke2` - Two device smoke tests
77+
- `@pytest.mark.smokevirt` - Virtual device smoke tests
78+
- `@pytest.mark.examples` - Example validation tests
79+
80+
### Running Tests
81+
82+
```bash
83+
# Run unit tests only (default)
84+
make test
85+
# or
86+
pytest -m unit
87+
88+
# Run all tests
89+
pytest
90+
91+
# Run with coverage
92+
make cov
93+
```
94+
95+
### Writing Tests
96+
97+
- Use `pytest` fixtures from `conftest.py`
98+
- Use `hypothesis` for property-based testing where appropriate
99+
- Mock external dependencies (serial ports, network connections)
100+
- Test file naming: `test_<module_name>.py`
101+
102+
## Pub/Sub Events
103+
104+
The library uses pypubsub for event handling. Key topics:
105+
106+
- `meshtastic.connection.established` - Connection successful
107+
- `meshtastic.connection.lost` - Connection lost
108+
- `meshtastic.receive.text(packet)` - Text message received
109+
- `meshtastic.receive.position(packet)` - Position update received
110+
- `meshtastic.receive.data.portnum(packet)` - Data packet by port number
111+
- `meshtastic.node.updated(node)` - Node database changed
112+
- `meshtastic.log.line(line)` - Raw log line from device
113+
114+
## Protocol Buffers
115+
116+
- Protobuf definitions are in `protobufs/meshtastic/`
117+
- Generated Python files are in `meshtastic/protobuf/`
118+
- Never edit `*_pb2.py` or `*_pb2.pyi` files directly
119+
- Regenerate with: `make protobufs` or `./bin/regen-protobufs.sh`
120+
121+
## Common Patterns
122+
123+
### Creating an Interface
124+
125+
```python
126+
import meshtastic.serial_interface
127+
128+
# Auto-detect device
129+
iface = meshtastic.serial_interface.SerialInterface()
130+
131+
# Specific device
132+
iface = meshtastic.serial_interface.SerialInterface(devPath="/dev/ttyUSB0")
133+
134+
# Always close when done
135+
iface.close()
136+
137+
# Or use context manager
138+
with meshtastic.serial_interface.SerialInterface() as iface:
139+
iface.sendText("Hello mesh")
140+
```
141+
142+
### Sending Messages
143+
144+
```python
145+
# Text message (broadcast)
146+
iface.sendText("Hello")
147+
148+
# Text message to specific node
149+
iface.sendText("Hello", destinationId="!abcd1234")
150+
151+
# Binary data
152+
iface.sendData(data, portNum=portnums_pb2.PRIVATE_APP)
153+
```
154+
155+
### Subscribing to Events
156+
157+
```python
158+
from pubsub import pub
159+
160+
def on_receive(packet, interface):
161+
print(f"Received: {packet}")
162+
163+
pub.subscribe(on_receive, "meshtastic.receive")
164+
```
165+
166+
## Development Workflow
167+
168+
1. Install dependencies: `poetry install --all-extras --with dev`
169+
2. Make changes
170+
3. Run linting: `poetry run pylint meshtastic examples/`
171+
4. Run type checking: `poetry run mypy meshtastic/`
172+
5. Run tests: `poetry run pytest -m unit`
173+
6. Update documentation if needed
174+
175+
## CLI Development
176+
177+
The CLI is in `meshtastic/__main__.py`. When adding new CLI commands:
178+
179+
- Use argparse for argument parsing
180+
- Support `--dest` for specifying target node
181+
- Provide `--help` documentation
182+
- Handle errors gracefully with meaningful messages
183+
184+
## Dependencies
185+
186+
### Required
187+
- `pyserial` - Serial port communication
188+
- `protobuf` - Protocol Buffers
189+
- `pypubsub` - Pub/sub messaging
190+
- `bleak` - BLE communication
191+
- `tabulate` - Table formatting
192+
- `pyyaml` - YAML config support
193+
- `requests` - HTTP requests
194+
195+
### Optional (extras)
196+
- `cli` extra: `pyqrcode`, `print-color`, `dotmap`, `argcomplete`
197+
- `tunnel` extra: `pytap2`
198+
- `analysis` extra: `dash`, `pandas`
199+
200+
## Important Notes
201+
202+
- Always test with actual Meshtastic hardware when possible
203+
- Be mindful of radio regulations in your region
204+
- The nodedb (`interface.nodes`) is read-only
205+
- Packet IDs are random 32-bit integers
206+
- Default timeout is 300 seconds for operations
Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: "Update protobufs"
22
on: workflow_dispatch
33

4+
permissions:
5+
contents: write
6+
47
jobs:
58
update-protobufs:
69
runs-on: ubuntu-latest
@@ -9,23 +12,34 @@ jobs:
912
- name: Checkout code
1013
uses: actions/checkout@v4
1114
with:
15+
fetch-depth: 0
1216
submodules: true
1317

14-
- name: Update Submodule
18+
- name: Setup Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.12"
22+
23+
- name: Install Poetry
1524
run: |
16-
git pull --recurse-submodules
25+
python -m pip install --upgrade pip
26+
python -m pip install poetry
27+
28+
- name: Update protobuf submodule
29+
run: |
30+
git submodule sync --recursive
31+
git submodule update --init --recursive
1732
git submodule update --remote --recursive
1833
1934
- name: Download nanopb
2035
run: |
21-
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz
36+
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
2237
tar xvzf nanopb-0.4.8-linux-x86.tar.gz
2338
mv nanopb-0.4.8-linux-x86 nanopb-0.4.8
2439
25-
- name: Install poetry (needed by regen-protobufs.sh)
40+
- name: Install Python dependencies
2641
run: |
27-
python -m pip install --upgrade pip
28-
pip3 install poetry
42+
poetry install --with dev
2943
3044
- name: Re-generate protocol buffers
3145
run: |
@@ -38,4 +52,9 @@ jobs:
3852
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
3953
git add protobufs
4054
git add meshtastic/protobuf
41-
git commit -m "Update protobuf submodule" && git push || echo "No changes to commit"
55+
if [[ -n "$(git status --porcelain)" ]]; then
56+
git commit -m "Update protobufs"
57+
git push
58+
else
59+
echo "No changes to commit"
60+
fi

0 commit comments

Comments
 (0)