#!/bin/bash set -e # Configuration REMOTE_HOST="10.0.0.1" REMOTE_USER="pi" REMOTE_DIR="~/sensorpajen-dev" REMOTE_VENV="$REMOTE_DIR/.venv" # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color log() { echo -e "${BLUE}[DEV-REMOTE]${NC} $1" } warn() { echo -e "${YELLOW}[WARNING]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" } cleanup() { log "Cleaning up..." # Kill the background python process if we stored its PID if [ ! -z "$BG_PID" ]; then log "Stopping remote dev backend (PID: $BG_PID)..." ssh -t $REMOTE_USER@$REMOTE_HOST "sudo kill $BG_PID 2>/dev/null || true" fi log "Restarting production service..." ssh -t $REMOTE_USER@$REMOTE_HOST "sudo systemctl start sensorpajen" log "Done." } # Trap cleanup on exit trap cleanup EXIT # Resolve script directory and project root SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # 1. Sync Code log "Syncing code from $PROJECT_ROOT to $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR..." rsync -avz --exclude '.venv' --exclude '__pycache__' --exclude '*.egg-info' \ --exclude '*.db' --exclude '*.db-*' --exclude '*.sqlite' --exclude '*.sqlite-*' \ "$PROJECT_ROOT/src" "$PROJECT_ROOT/scripts" "$PROJECT_ROOT/pyproject.toml" "$PROJECT_ROOT/config" \ "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" # 2. Setup Remote Environment (Initial setup) log "Ensuring remote environment is ready..." ssh -t $REMOTE_USER@$REMOTE_HOST " mkdir -p $REMOTE_DIR cd $REMOTE_DIR # Install system dependencies (always check) echo 'Checking system dependencies...' # Only run apt-get update if we need to install something to save time? # Or just run it. Let's run install, it's safer. if ! dpkg -s libbluetooth-dev >/dev/null 2>&1; then echo 'Installing libbluetooth-dev...' sudo apt-get update sudo apt-get install -y libbluetooth-dev python3-dev fi # Create venv if missing if [ ! -d .venv ]; then echo 'Creating virtual environment...' python3 -m venv .venv fi # Install/Update dependencies echo 'Installing dependencies (forcing reinstall to ensure code update)...' .venv/bin/pip install --upgrade pip .venv/bin/pip install --force-reinstall --no-deps . # Verify code sync echo 'Verifying code sync...' if grep -q "sensor_config=self.sensor_config" src/sensorpajen/main.py; then echo "✅ main.py has latest changes." else echo "❌ main.py does NOT have latest changes! Rsync might have failed." fi # Ensure config exists (copy from system or examples if totally missing) if [ ! -d config ]; then mkdir config; fi # Rename DB to match default expectation in config.py (sensorpajen.db) if it was copied as discovered_sensors.db # Blindly try to copy with sudo since we can't check existence in restricted dir echo 'Copying config files from /etc/sensorpajen (blindly due to permissions)...' # DB # Only copy if they don't exist locally to preserve dev data if [ ! -f config/sensorpajen.db ]; then echo 'Copying database from system...' # Try discovered_sensors.db first, then sensorpajen.db if [ -f /etc/sensorpajen/discovered_sensors.db ]; then sudo cp /etc/sensorpajen/discovered_sensors.db config/sensorpajen.db 2>/dev/null || true elif [ -f /etc/sensorpajen/sensorpajen.db ]; then sudo cp /etc/sensorpajen/sensorpajen.db config/sensorpajen.db 2>/dev/null || true fi # Ensure correct ownership immediately after copy sudo chown $REMOTE_USER:$REMOTE_USER config/sensorpajen.db 2>/dev/null || true else echo 'Preserving existing database config/sensorpajen.db' fi # Configs # Only copy if they don't exist locally to preserve dev changes if [ ! -f config/sensors.json ]; then echo 'Copying sensors.json from system...' sudo cp /etc/sensorpajen/sensors.json config/sensors.json 2>/dev/null || true else echo 'Preserving existing config/sensors.json' fi if [ ! -f config/sensorpajen.env ]; then echo 'Copying sensorpajen.env from system...' sudo cp /etc/sensorpajen/sensorpajen.env config/sensorpajen.env 2>/dev/null || true else echo 'Preserving existing config/sensorpajen.env' fi # ALWAYS sanitize sensorpajen.env to ensure we don't use system paths # and set explicit dev paths if [ -f config/sensorpajen.env ]; then echo 'Sanitizing and setting dev paths in config/sensorpajen.env...' sudo sed -i '/^SENSOR_CONFIG_FILE/d' config/sensorpajen.env sudo sed -i '/^DATABASE_FILE/d' config/sensorpajen.env sudo sed -i '/^DISCOVERED_SENSORS_FILE/d' config/sensorpajen.env # Add dev paths explicitly (use absolute paths since we're in ssh context) echo "SENSOR_CONFIG_FILE=/home/$REMOTE_USER/sensorpajen-dev/config/sensors.json" | sudo tee -a config/sensorpajen.env > /dev/null echo "DATABASE_FILE=/home/$REMOTE_USER/sensorpajen-dev/config/sensorpajen.db" | sudo tee -a config/sensorpajen.env > /dev/null echo "DISCOVERED_SENSORS_FILE=/home/$REMOTE_USER/sensorpajen-dev/config/discovered_sensors.json" | sudo tee -a config/sensorpajen.env > /dev/null fi # Examples (if real config missing) # We don't need to do anything here, the rsync already brought examples if they exist locally # FIX OWNERSHIP recursively echo 'Fixing permissions...' sudo chown -R $REMOTE_USER:$REMOTE_USER $REMOTE_DIR " # 3. Stop Production Service log "Stopping production service to free up Bluetooth..." ssh -t $REMOTE_USER@$REMOTE_HOST "sudo systemctl stop sensorpajen" # 4. Run Dev Backend in Background log "Starting DEV backend on remote..." # Grant capabilities to the venv python ssh -t $REMOTE_USER@$REMOTE_HOST " cd $REMOTE_DIR PYTHON_BIN=\$(readlink -f .venv/bin/python3) # Install libcap2-bin if missing if ! command -v setcap &> /dev/null; then sudo apt-get install -y libcap2-bin fi sudo setcap cap_net_raw,cap_net_admin+eip \"\$PYTHON_BIN\" " # Run backend as USER (not sudo) so DB files are owned by user # Source env vars if available ssh $REMOTE_USER@$REMOTE_HOST " cd $REMOTE_DIR if [ -f config/sensorpajen.env ]; then set -a source config/sensorpajen.env set +a fi .venv/bin/python3 -m sensorpajen.main > dev_backend.log 2>&1 & echo \$! " > .remote_pid BG_PID=$(cat .remote_pid) rm .remote_pid log "Dev backend started with PID: $BG_PID" # Wait a moment for backend to initialize DB sleep 3 # 5. Run TUI log "Launching TUI..." log "${GREEN}Disconnecting will stop the dev backend and restart the service.${NC}" ssh -t $REMOTE_USER@$REMOTE_HOST " cd $REMOTE_DIR source .venv/bin/activate if [ -f config/sensorpajen.env ]; then set -a source config/sensorpajen.env set +a fi export TUI_LOG_FILE=dev_backend.log # Run TUI python3 -m sensorpajen.tui.app " # Cleanup happens via trap