#!/bin/bash # # 20260602 ChatGPT # $Id$ # $HeadURL$ # # Example command lines: # # ./load_only.sh --tbeams "CY" # ./load_only.sh --tbeams "DAN" # ./load_only.sh --tbeams "BOB" # ./load_only.sh --tbeams "BOB CY DAN" # ./load_only.sh --tbeams "bob,cy,dan" # # If pio/platformio is not in PATH: # # ./load_only.sh --pio-bin "$HOME/pioenv/bin/platformio" --tbeams "DAN" # set -euo pipefail EXERCISE="/usr/local/src/microreticulum/microReticulumTbeam/exercises/204_established_identities" REMOTE_HOST="ryzdesk" TBEAMS_RAW="" PIO_BIN="" usage() { cat <<'EOF' Usage: ./load_only.sh --tbeams "CY" ./load_only.sh --tbeams "BOB CY DAN" ./load_only.sh --tbeams "bob,cy,dan" Required: --tbeams One or more of: AMY BOB CY DAN ED FLO GUY Optional: --pio-bin Full path to pio/platformio executable --exercise PlatformIO project directory --remote Remote build host, default: ryzdesk EOF } while [ "$#" -gt 0 ] do case "$1" in --tbeams) shift [ "$#" -gt 0 ] || { echo "ERROR: --tbeams requires a value" >&2; exit 1; } TBEAMS_RAW="$1" ;; --pio-bin) shift [ "$#" -gt 0 ] || { echo "ERROR: --pio-bin requires a value" >&2; exit 1; } PIO_BIN="$1" ;; --exercise) shift [ "$#" -gt 0 ] || { echo "ERROR: --exercise requires a value" >&2; exit 1; } EXERCISE="$1" ;; --remote) shift [ "$#" -gt 0 ] || { echo "ERROR: --remote requires a value" >&2; exit 1; } REMOTE_HOST="$1" ;; -h|--help) usage exit 0 ;; *) echo "ERROR: unknown option: $1" >&2 usage >&2 exit 1 ;; esac shift done if [ -z "$TBEAMS_RAW" ]; then echo "ERROR: missing required option --tbeams" >&2 usage >&2 exit 1 fi if [ ! -d "$EXERCISE" ]; then echo "ERROR: EXERCISE directory not found: $EXERCISE" >&2 exit 1 fi if [ ! -f "$EXERCISE/platformio.ini" ]; then echo "ERROR: platformio.ini not found under: $EXERCISE" >&2 exit 1 fi if [ -n "$PIO_BIN" ]; then if [ ! -x "$PIO_BIN" ]; then echo "ERROR: --pio-bin is not executable: $PIO_BIN" >&2 exit 1 fi else if command -v pio >/dev/null 2>&1; then PIO_BIN="$(command -v pio)" elif command -v platformio >/dev/null 2>&1; then PIO_BIN="$(command -v platformio)" else echo "ERROR: cannot find pio or platformio in PATH" >&2 echo " Try: --pio-bin \"\$HOME/pioenv/bin/platformio\"" >&2 exit 1 fi fi echo "EXERCISE: $EXERCISE" echo "REMOTE_HOST: $REMOTE_HOST" echo "PIO_BIN: $PIO_BIN" echo # # Accept either: # "BOB CY DAN" # "bob,cy,dan" # TBEAMS_NORMALIZED="$(echo "$TBEAMS_RAW" | tr ',' ' ')" for env_raw in $TBEAMS_NORMALIZED do env="$(echo "$env_raw" | tr '[:upper:]' '[:lower:]')" ENV="$(echo "$env" | tr '[:lower:]' '[:upper:]')" case "$env" in amy|bob|cy|dan|ed|flo|guy) ;; *) echo "ERROR: invalid T-Beam name: $env_raw" >&2 echo " Allowed names: AMY BOB CY DAN ED FLO GUY" >&2 exit 1 ;; esac dev="/dev/ttyt${ENV}" remote_build_dir="${EXERCISE}/.pio/build/${env}" local_build_dir="${EXERCISE}/.pio/build/${env}" if [ ! -e "$dev" ]; then echo "ERROR: expected device not found for $ENV: $dev" >&2 exit 1 fi if ! ssh "$REMOTE_HOST" "test -d '$remote_build_dir'"; then echo "ERROR: remote build directory missing on ${REMOTE_HOST}: $remote_build_dir" >&2 exit 1 fi if [ ! -d "$local_build_dir" ]; then echo "Creating missing local build directory: $local_build_dir" mkdir -p "$local_build_dir" || { echo "ERROR: failed to create $local_build_dir" >&2 exit 1 } fi echo "===== copy built artifact tree for $env from $REMOTE_HOST =====" rsync -a \ "${REMOTE_HOST}:${remote_build_dir}/" \ "${local_build_dir}/" if [ ! -f "${local_build_dir}/firmware.bin" ] && [ ! -f "${local_build_dir}/firmware.elf" ]; then echo "ERROR: copied build tree does not appear to contain firmware output:" >&2 echo " $local_build_dir" >&2 exit 1 fi echo "===== loader-only upload $ENV on $dev =====" "$PIO_BIN" run \ -d "$EXERCISE" \ -e "$env" \ -t nobuild \ -t upload \ --upload-port "$dev" echo "===== finished loader-only upload for $ENV =====" echo done