Merge pull request #12 from torlando-tech/fix/issue-11-pipx-dbus

docs: add pipx installation instructions and troubleshooting
This commit is contained in:
torlando-tech 2025-11-15 21:05:41 -05:00 committed by GitHub
commit 79a4c3179f
2 changed files with 196 additions and 9 deletions

113
README.md
View file

@ -39,9 +39,9 @@ chmod +x install.sh
```
The script will:
1. ✓ Detect if Reticulum is in a venv or system-wide
2. ✓ Install system dependencies (BlueZ, dbus)
3. ✓ Install Python packages in the correct environment
1. ✓ Detect if Reticulum is in a venv, pipx, or system-wide
2. ✓ Install system dependencies (BlueZ, dbus, build tools if needed)
3. ✓ Install Python packages in the correct environment (via pipx inject if needed)
4. ✓ Copy BLE interface files to `~/.reticulum/interfaces/` (or custom config directory if specified)
5. ✓ Enable BlueZ experimental mode (required for proper BLE connectivity)
6. ✓ Optionally set up Bluetooth permissions
@ -150,6 +150,99 @@ sudo setcap 'cap_net_raw,cap_net_admin+eip' $(which python3)
sudo setcap 'cap_net_raw,cap_net_admin+eip' /path/to/venv/bin/python3
```
### Option C: pipx Installation (RNS installed via pipx)
If you installed Reticulum via `pipx install rns`, the BLE interface requires additional setup because pipx creates isolated virtual environments that cannot access system-installed packages.
**Note:** The automated installation script (Option A: `./install.sh`) now detects and handles pipx installations automatically. The instructions below are for manual installation or troubleshooting.
#### 1. Install System Dependencies
**Arch Linux:**
```bash
sudo pacman -S base-devel gobject-introspection python-dbus python-cairo bluez bluez-utils
```
**Debian/Ubuntu/Raspberry Pi OS:**
```bash
sudo apt-get update
sudo apt-get install build-essential python3-dev python3-gi python3-dbus python3-cairo bluez libdbus-1-dev
```
#### 2. Inject BLE Dependencies into pipx Environment
Because pipx creates isolated environments, you must inject the BLE dependencies into the RNS environment:
```bash
# Inject BLE dependencies into pipx RNS environment
pipx inject rns bleak==1.1.1 bluezero dbus-python
```
**Note:** This will compile `dbus-python` from source, which requires the system development libraries installed in step 1.
#### 3. Copy BLE Interface Files
```bash
# Copy to Reticulum's interface directory
mkdir -p ~/.reticulum/interfaces
cp src/RNS/Interfaces/BLE*.py ~/.reticulum/interfaces/
```
#### 4. Grant Bluetooth Permissions
Find the Python executable used by pipx for RNS:
```bash
# Find pipx RNS Python path
PIPX_RNS_PYTHON=$(pipx runpip rns show rns | grep Location | awk '{print $2}' | sed 's/lib\/python.*/bin\/python3/')
# Grant capabilities
sudo setcap 'cap_net_raw,cap_net_admin+eip' "$PIPX_RNS_PYTHON"
```
Alternatively, find the path manually:
```bash
# List pipx environments
ls ~/.local/pipx/venvs/
# Grant capabilities to the rns venv Python
sudo setcap 'cap_net_raw,cap_net_admin+eip' ~/.local/pipx/venvs/rns/bin/python3
```
#### 5. Enable BlueZ Experimental Mode
The BLE interface requires BlueZ experimental features for proper BLE connectivity:
```bash
# Edit BlueZ service configuration
sudo systemctl edit bluetooth.service
```
Add the following content:
```ini
[Service]
ExecStart=
ExecStart=/usr/lib/bluetooth/bluetoothd --experimental
```
Then reload and restart:
```bash
sudo systemctl daemon-reload
sudo systemctl restart bluetooth.service
# Verify experimental mode is enabled
systemctl status bluetooth.service | grep -i experimental
```
#### Why pipx Requires Special Handling
pipx creates isolated virtual environments with `--no-site-packages` to prevent package conflicts. This means:
- System packages like `python-dbus` (installed via apt/pacman) are not accessible
- `dbus-python` must be compiled from source within the pipx environment
- `pipx inject` installs packages directly into RNS's isolated environment
This isolation is intentional and prevents conflicts, but requires the extra injection step for system-dependent packages like `dbus-python`.
## Quick Start
### 1. Configure Reticulum
@ -297,6 +390,20 @@ sudo systemctl start bluetooth
The automated installer (v1.x+) automatically checks and powers on the Bluetooth adapter during installation.
### pipx: ModuleNotFoundError for dbus, gi, or bluezero
If you installed RNS via pipx and get import errors like `ModuleNotFoundError: No module named 'dbus'`, `No module named 'gi'`, or `No module named 'bluezero'`:
**Cause:** pipx creates isolated environments that don't access system packages.
**Solution:** Follow the [pipx installation instructions](#option-c-pipx-installation-rns-installed-via-pipx) to inject the required dependencies:
```bash
pipx inject rns bleak==1.1.1 bluezero dbus-python
```
**Verification:** Test if the modules are accessible:
```bash
pipx run rns python3 -c "import dbus, gi, bleak, bluezero; print('All modules found')"
```
## Architecture
The BLE interface consists of four main components:

View file

@ -237,6 +237,7 @@ print_header "Checking for Reticulum"
RNS_VENV=""
RNS_PYTHON=""
INSTALL_MODE=""
PIPX_RNS_PATH=""
# Add user's local bin to PATH if it exists (common pip install location)
if [ -d "$HOME/.local/bin" ]; then
@ -253,8 +254,41 @@ if command -v rnsd &> /dev/null; then
if [ -n "$RNS_LOCATION" ]; then
print_success "Found RNS Python package at: $RNS_LOCATION"
# Check if it's a pipx installation (most specific, check first)
if [[ "$RNS_LOCATION" == *"/pipx/venvs/"* ]]; then
print_info "RNS appears to be installed via pipx"
# Verify pipx command is available
if ! command -v pipx &> /dev/null; then
print_error "RNS is in a pipx path, but pipx command not found!"
echo
echo "Please install pipx:"
echo " python3 -m pip install --user pipx"
echo " python3 -m pipx ensurepath"
exit 1
fi
# Verify RNS is listed in pipx
if pipx list 2>/dev/null | grep -q "package rns"; then
INSTALL_MODE="pipx"
# Extract pipx venv path (e.g., ~/.local/pipx/venvs/rns)
PIPX_RNS_PATH=$(echo "$RNS_LOCATION" | grep -oP '^.*?/pipx/venvs/rns')
RNS_PYTHON="$PIPX_RNS_PATH/bin/python3"
if [ ! -f "$RNS_PYTHON" ]; then
print_error "pipx Python not found at: $RNS_PYTHON"
exit 1
fi
print_success "Detected pipx installation at: $PIPX_RNS_PATH"
else
print_error "RNS appears to be in pipx path, but 'pipx list' doesn't show it"
echo "Run 'pipx list' to verify your pipx installations"
exit 1
fi
# Check if it's in a virtual environment
if [[ "$RNS_LOCATION" == *"/venv/"* ]] || [[ "$RNS_LOCATION" == *"/env/"* ]] || [[ "$VIRTUAL_ENV" != "" ]]; then
elif [[ "$RNS_LOCATION" == *"/venv/"* ]] || [[ "$RNS_LOCATION" == *"/env/"* ]] || [[ "$VIRTUAL_ENV" != "" ]]; then
# RNS is in a venv
if [ -n "$VIRTUAL_ENV" ]; then
RNS_VENV="$VIRTUAL_ENV"
@ -365,9 +399,47 @@ if [[ "$ARCH" == "armhf" ]] || [[ "$(uname -m)" =~ ^(armv6l|armv7l)$ ]]; then
fi
fi
print_info "Installing pip packages (PyGObject, dbus-python, pycairo provided by system packages)"
if [ "$INSTALL_MODE" = "pipx" ]; then
print_info "Installing dependencies via pipx inject..."
print_warning "dbus-python will be compiled from source (may take 2-3 minutes)"
echo
if [ "$INSTALL_MODE" = "venv" ]; then
# Define dependencies (must match requirements.txt)
DEPS=("bleak==1.1.1" "bluezero" "dbus-python")
# Inject each dependency individually
for dep in "${DEPS[@]}"; do
print_info "Injecting $dep into RNS environment..."
if pipx inject rns "$dep"; then
print_success "Injected $dep"
else
print_error "Failed to inject $dep"
echo
echo "Common causes:"
echo " - Missing system build dependencies (see above)"
echo " - Network connectivity issues"
echo
echo "Try manually:"
echo " pipx inject rns $dep --verbose"
exit 1
fi
echo
done
# Verify all modules can be imported
print_info "Verifying dependencies..."
if "$RNS_PYTHON" -c "import bleak, bluezero, dbus" 2>/dev/null; then
print_success "All dependencies verified and working"
else
print_error "Dependency verification failed"
echo
echo "Test imports manually:"
echo " $RNS_PYTHON -c 'import bleak, bluezero, dbus'"
exit 1
fi
elif [ "$INSTALL_MODE" = "venv" ]; then
print_info "Installing to virtual environment: $RNS_VENV"
if [ ! -f "$RNS_PYTHON" ]; then
@ -494,9 +566,17 @@ else
print_info "Running as root - skipping capability grant (not needed)"
print_info "Root user already has all required Bluetooth permissions"
elif command -v setcap &> /dev/null; then
# Get python3 path
PYTHON_PATH=$(which python3)
print_info "Detected Python at: $PYTHON_PATH"
# Determine correct Python path based on installation mode
if [ "$INSTALL_MODE" = "pipx" ]; then
PYTHON_PATH="$PIPX_RNS_PATH/bin/python3"
print_info "Using pipx Python: $PYTHON_PATH"
elif [ "$INSTALL_MODE" = "venv" ]; then
PYTHON_PATH="$RNS_VENV/bin/python3"
print_info "Using venv Python: $PYTHON_PATH"
else
PYTHON_PATH=$(which python3)
print_info "Using system Python: $PYTHON_PATH"
fi
# Check if it's a symlink and resolve it
if [ -L "$PYTHON_PATH" ]; then