Merge pull request #12 from torlando-tech/fix/issue-11-pipx-dbus
docs: add pipx installation instructions and troubleshooting
This commit is contained in:
commit
3e3de053cb
2 changed files with 196 additions and 9 deletions
113
README.md
113
README.md
|
|
@ -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:
|
||||
|
|
|
|||
92
install.sh
92
install.sh
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue