12 KiB
Development Guide
Last Updated: December 31, 2025
This guide provides instructions for setting up a development environment, running tests, and contributing to the Akita Meshtastic Meshcore Bridge (AMMB) project.
Setting Up Development Environment
-
Clone the repository:
git clone https://github.com/AkitaEngineering/akita-meshtastic-meshcore-bridge.git cd akita-meshtastic-meshcore-bridge -
Create and activate a Python virtual environment:
python -m venv venv # On Windows: .\venv\Scripts\activate # On Linux/macOS: source venv/bin/activateUsing a virtual environment isolates project dependencies.
-
Install runtime and development dependencies:
pip install -r requirements.txt pip install -r requirements-dev.txtThis installs runtime dependencies (
meshtastic,pyserial,pypubsub,paho-mqtt) and development tools (pytest,pytest-cov,flake8,mypy).
Project Structure
akita-meshtastic-meshcore-bridge/
├── ammb/ # Main package
│ ├── __init__.py
│ ├── bridge.py # Bridge orchestrator
│ ├── config_handler.py # Configuration management
│ ├── meshtastic_handler.py # Meshtastic network handler
│ ├── meshcore_handler.py # Serial handler
│ ├── mqtt_handler.py # MQTT handler
│ ├── protocol.py # Serial protocol handlers
│ ├── utils.py # Utility functions
│ ├── metrics.py # Metrics collection
│ ├── health.py # Health monitoring
│ ├── api.py # REST API server
│ ├── validator.py # Message validation
│ ├── rate_limiter.py # Rate limiting
│ └── message_logger.py # Message persistence
├── tests/ # Test suite
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_config_handler.py
│ └── test_protocol.py
├── docs/ # Documentation
│ ├── architecture.md
│ ├── configuration.md
│ ├── development.md
│ └── usage.md
├── examples/ # Example files
│ ├── config.ini.example
│ └── meshcore_simulator.py
├── run_bridge.py # Main entry point
├── requirements.txt # Runtime dependencies
├── requirements-dev.txt # Development dependencies
└── README.md # Project overview
Running Tests
The project uses pytest for automated testing.
-
Ensure your virtual environment is active.
-
Navigate to the project root directory.
-
Run all tests:
pytestThis will discover and run all tests located in the
tests/directory. -
Run tests with coverage report:
pytest --cov=ammb --cov-report term-missingThis runs the tests and generates a report showing which lines of the source code in the
ammb/directory were executed by the tests. -
Run specific test file:
pytest tests/test_protocol.py -
Run with verbose output:
pytest -v
Code Style and Linting
We use flake8 for checking code style against PEP 8 guidelines and common errors.
-
Ensure your virtual environment is active.
-
Navigate to the project root directory.
-
Run flake8:
flake8 ammb/ tests/ run_bridge.pyThis will report any style violations or potential errors. Aim for zero reported issues.
-
Check specific file:
flake8 ammb/bridge.py
Project linting policy ✅
- Max line length: 79 characters (flake8 E501). When long lines are found, prefer targeted wrapping or splitting (for example: split long strings, break complex expressions, or use short helper variables) rather than increasing the line length limit.
- Third-party packages: Do not edit files under
.venvor other external package directories to satisfy linter rules. Instead, exclude those directories from lint runs (we include.venvin the project's.flake8file). - Logging: Prefer parameterized logging calls (e.g.,
logger.info("Connected to %s", port)) instead of long f-strings to keep messages shorter and avoid unnecessary formatting overhead. - Fix process: When addressing E501 issues in project files, make conservative, behavior-preserving edits (wrap strings, reflow docstrings, or adjust logging). Re-run tests and
mypyafter each change to ensure no regressions.
Example: In this revision we fixed several E501 cases in ammb/ and examples/ by wrapping long strings and using parameterized logging; tests and mypy were re-run to confirm the project remains correct.
Static Type Checking
We use mypy for static type checking to catch potential type-related errors before runtime.
-
Ensure your virtual environment is active.
-
Navigate to the project root directory.
-
Run mypy:
mypy ammb/ run_bridge.pyThis will analyze the type hints in the code and report any inconsistencies or errors. Aim for zero reported issues.
-
Check specific module:
mypy ammb/bridge.py
Code Quality Standards
Type Hints
All function signatures should include type hints:
def process_message(message: Dict[str, Any]) -> bool:
"""Process a message and return success status."""
...
Documentation Strings
All public functions and classes should have docstrings:
class MessageHandler:
"""Handles message processing and validation."""
def validate(self, data: str) -> bool:
"""
Validate message data.
Args:
data: Message data to validate
Returns:
True if valid, False otherwise
"""
...
Error Handling
Use appropriate exception handling:
try:
result = risky_operation()
except SpecificException as e:
logger.error(f"Operation failed: {e}", exc_info=True)
return None
Thread Safety
All shared data structures must use locks:
class ThreadSafeCounter:
def __init__(self):
self._count = 0
self._lock = threading.Lock()
def increment(self):
with self._lock:
self._count += 1
Contribution Guidelines
We welcome contributions! Please follow these steps:
-
Fork the repository on GitHub.
-
Clone your fork locally:
git clone https://github.com/YOUR_FORK_USERNAME/akita-meshtastic-meshcore-bridge.git -
Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature-name # or git checkout -b fix/issue-description -
Set up your development environment as described above.
-
Make your changes. Ensure you:
- Follow the existing code style
- Add type hints to all functions
- Write docstrings for public APIs
- Add tests for new features or bug fixes
- Update documentation if necessary
- Ensure all tests pass (
pytest) - Ensure linters pass (
flake8 ammb/ tests/ run_bridge.py) - Ensure type checks pass (
mypy ammb/ run_bridge.py)
-
Commit your changes with clear and descriptive commit messages:
git commit -m "Add feature: description of what was added" git commit -m "Fix bug: description of what was fixed" -
Push your branch to your fork:
git push origin feature/your-feature-name -
Open a Pull Request (PR) from your fork's branch to the
mainbranch of the original repository. -
Clearly describe the changes made in the PR description and link to any relevant issues.
-
Respond to feedback or requested changes during the code review process.
Adding New Features
Adding New Serial Protocols
To support a different serial protocol:
-
Create a new class in
ammb/protocol.pythat inherits fromMeshcoreProtocolHandler. -
Implement the required methods:
class YourProtocol(MeshcoreProtocolHandler): def read(self, serial_port) -> Optional[bytes]: """Read data from serial port.""" ... def encode(self, data: Dict[str, Any]) -> Optional[bytes]: """Encode dictionary to bytes.""" ... def decode(self, raw_data: bytes) -> Optional[Dict[str, Any]]: """Decode bytes to dictionary.""" ... -
Update the
get_serial_protocol_handler()factory function inammb/protocol.py:_serial_protocol_handlers = { 'json_newline': JsonNewlineProtocol, 'raw_serial': RawSerialProtocol, 'your_protocol': YourProtocol, # Add here } -
Add the new protocol name as an option for the
SERIAL_PROTOCOLsetting in:docs/configuration.mdexamples/config.ini.example
-
Add tests for your new protocol handler in
tests/test_protocol.py.
Adding New External Transports
To add a new external transport (e.g., HTTP, WebSocket):
-
Create a new handler class similar to
MeshcoreHandlerorMQTTHandler:class YourTransportHandler: def __init__(self, config, to_meshtastic_queue, from_meshtastic_queue, shutdown_event): # Initialize with metrics, health, validator, rate_limiter ... def connect(self) -> bool: # Implement connection logic ... def start_publisher(self): # Start background threads if needed ... def stop(self): # Clean shutdown ... -
Integrate with existing systems:
- Use
get_metrics()for metrics collection - Use
get_health_monitor()for health tracking - Use
MessageValidatorfor validation - Use
RateLimiterfor rate limiting
- Use
-
Add to
Bridgeclass initialization inammb/bridge.py. -
Update configuration handler to support new transport settings.
-
Add tests for the new transport handler.
Adding New API Endpoints
To add new REST API endpoints:
-
Add handler method in
BridgeAPIHandlerclass inammb/api.py:def _handle_your_endpoint(self): """Handle your new endpoint.""" data = {"your": "data"} self._send_response(200, data) -
Add route in
do_GET()ordo_POST()method:elif path == '/api/your_endpoint': self._handle_your_endpoint() -
Update API documentation in
docs/usage.md.
Testing Guidelines
Unit Tests
Write unit tests for individual functions and classes:
def test_message_validation():
validator = MessageValidator()
valid_msg = {"destination": "^all", "text": "Hello"}
is_valid, error = validator.validate_meshtastic_message(valid_msg)
assert is_valid
assert error is None
Integration Tests
Write integration tests for component interactions:
def test_bridge_initialization():
config = load_config("test_config.ini")
bridge = Bridge(config)
assert bridge.meshtastic_handler is not None
assert bridge.external_handler is not None
Test Fixtures
Use pytest fixtures for common test setup:
@pytest.fixture
def test_config(tmp_path):
config_path = tmp_path / "config.ini"
# Create test configuration
return config_path
Debugging
Enable Debug Logging
Set LOG_LEVEL = DEBUG in config.ini for detailed logging.
Use Python Debugger
Add breakpoints in code:
import pdb; pdb.set_trace()
Or use IDE debugger with breakpoints.
Check Metrics
Use the REST API to check metrics:
curl http://localhost:8080/api/metrics
Check Health Status
Use the REST API to check health:
curl http://localhost:8080/api/health
Release Process
When preparing a release:
- Update version in
ammb/__init__.py - Update
CHANGELOG.mdwith release notes - Update documentation dates
- Run full test suite
- Run linters and type checkers
- Create git tag
- Push to repository
Getting Help
If you need help with development:
- Check existing documentation
- Review code comments
- Check test examples
- Open an issue on GitHub
- Contact maintainers