From 8799239ab37835a8b8a92a9daa0fd7ed0c54e31a Mon Sep 17 00:00:00 2001 From: Adamskiee Date: Mon, 17 Aug 2026 19:06:12 +0800 Subject: [PATCH 1/3] feat(deploy-bundle): auto-detect and sync arduino serial port. Modified install.sh to automatically detect connected GSM Arduino ports and present an interactive selection menu. This replaces the manual boolean prompt and automatically synchronizes the selected port to both gsm-arduino.env and gsm-fastapi.env. --- deploy/scripts/install.sh | 43 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/deploy/scripts/install.sh b/deploy/scripts/install.sh index cab2d207..f7073804 100755 --- a/deploy/scripts/install.sh +++ b/deploy/scripts/install.sh @@ -22,8 +22,47 @@ ip=$($target/certs/detect-ip.sh 2>/dev/null || true) [ -n "$ip" ] || { read -r -p "LAN IP for TLS certificate: " ip; } ca_issue_leaf "$SAPOT_ROOT/shared/certs" "$ip" "$ca_dir" false log_info "certificate issued - the CA USB stick can be unplugged now" -read -r -p "Is the GSM Arduino connected at $(grep '^GSM_ARDUINO_PORT=' "$SAPOT_ROOT/shared/gsm-arduino.env" | cut -d= -f2)? [y/N] " answer -hardware=false; [[ "$answer" =~ ^[Yy]$ ]] && hardware=true +shopt -s nullglob +detected_ports=(/dev/ttyACM* /dev/ttyUSB*) +shopt -u nullglob + +hardware=false +selected_port="" + +if [ ${#detected_ports[@]} -eq 0 ]; then + read -r -p "No GSM Arduino detected. Enter port path manually or leave empty to skip: " answer + if [ -n "$answer" ]; then + selected_port="$answer" + hardware=true + fi +elif [ ${#detected_ports[@]} -eq 1 ]; then + read -r -p "Found GSM Arduino at ${detected_ports[0]}. Use this? [Y/n/custom] " answer + if [[ "$answer" =~ ^[Yy]$ ]] || [ -z "$answer" ]; then + selected_port="${detected_ports[0]}" + hardware=true + elif [[ "$answer" =~ ^[Cc]ustom$ ]]; then + read -r -p "Enter custom port path: " selected_port + if [ -n "$selected_port" ]; then hardware=true; fi + fi +else + echo "Multiple GSM Arduino devices found:" + for i in "${!detected_ports[@]}"; do + echo " $((i+1))) ${detected_ports[$i]}" + done + read -r -p "Select a number, type a custom path, or leave empty to skip: " answer + if [[ "$answer" =~ ^[0-9]+$ ]] && [ "$answer" -ge 1 ] && [ "$answer" -le "${#detected_ports[@]}" ]; then + selected_port="${detected_ports[$((answer-1))]}" + hardware=true + elif [ -n "$answer" ]; then + selected_port="$answer" + hardware=true + fi +fi + +if [ "$hardware" = true ] && [ -n "$selected_port" ]; then + sed -i "s|^GSM_ARDUINO_PORT=.*|GSM_ARDUINO_PORT=$selected_port|" "$SAPOT_ROOT/shared/gsm-arduino.env" + sed -i "s|^SERIAL_PORT=.*|SERIAL_PORT=$selected_port|" "$SAPOT_ROOT/shared/gsm-fastapi.env" +fi for image in "$target"/images/*.tar; do load_image_archive "$image"; done "$VERIFY_DIGESTS" "$target/manifest.json" compose "$target" up -d db redis; wait_healthy "$target" db; wait_healthy "$target" redis From 96780604f169833f095ff1b1f6e0337ab999f0d2 Mon Sep 17 00:00:00 2001 From: Adamskiee Date: Tue, 18 Aug 2026 11:30:45 +0800 Subject: [PATCH 2/3] feat(deploy-bundle): add GSM auto-detect prompt to upgrade.sh for old versions Updates upgrade.sh to conditionally prompt for GSM Arduino port auto-detection if the currently deployed bundle version is older than 0.0.8 and GSM hardware is not already configured. --- deploy/scripts/upgrade.sh | 49 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/deploy/scripts/upgrade.sh b/deploy/scripts/upgrade.sh index fde38bfe..0b772c8e 100755 --- a/deploy/scripts/upgrade.sh +++ b/deploy/scripts/upgrade.sh @@ -13,6 +13,53 @@ version=$(manifest_value "$source_manifest" version) target="$SAPOT_ROOT/releases/v$version" disk_preflight "$source_release" "$target" "$(manifest_value "$source_manifest" requiredDiskBytes)" mkdir -p "$SAPOT_ROOT/releases"; [ -e "$target" ] || cp -a "$source_release" "$target" + +hardware=$(manifest_value "$SAPOT_ROOT/shared/state.json" gsmHardwarePresent) +selected_port="" + +if [ "$(python3 "$SEMVER" compare "$current_version" "0.0.8")" -lt 0 ] && [ "$hardware" != "true" ]; then + shopt -s nullglob + detected_ports=(/dev/ttyACM* /dev/ttyUSB*) + shopt -u nullglob + + if [ ${#detected_ports[@]} -eq 0 ]; then + read -r -p "No GSM Arduino detected. Enter port path manually or leave empty to keep current setting: " answer + if [ -n "$answer" ]; then + selected_port="$answer" + hardware=true + fi + elif [ ${#detected_ports[@]} -eq 1 ]; then + read -r -p "Found GSM Arduino at ${detected_ports[0]}. Use this? [Y/n/custom/skip] " answer + if [[ "$answer" =~ ^[Yy]$ ]] || [ -z "$answer" ]; then + selected_port="${detected_ports[0]}" + hardware=true + elif [[ "$answer" =~ ^[Cc]ustom$ ]]; then + read -r -p "Enter custom port path: " selected_port + if [ -n "$selected_port" ]; then hardware=true; fi + elif [[ "$answer" =~ ^[Nn]$ ]]; then + hardware=false + fi + else + echo "Multiple GSM Arduino devices found:" + for i in "${!detected_ports[@]}"; do + echo " $((i+1))) ${detected_ports[$i]}" + done + read -r -p "Select a number, type a custom path, or leave empty to keep current setting: " answer + if [[ "$answer" =~ ^[0-9]+$ ]] && [ "$answer" -ge 1 ] && [ "$answer" -le "${#detected_ports[@]}" ]; then + selected_port="${detected_ports[$((answer-1))]}" + hardware=true + elif [ -n "$answer" ]; then + selected_port="$answer" + hardware=true + fi + fi + + if [ "$hardware" = true ] && [ -n "$selected_port" ]; then + sed -i "s|^GSM_ARDUINO_PORT=.*|GSM_ARDUINO_PORT=$selected_port|" "$SAPOT_ROOT/shared/gsm-arduino.env" + sed -i "s|^SERIAL_PORT=.*|SERIAL_PORT=$selected_port|" "$SAPOT_ROOT/shared/gsm-fastapi.env" + fi +fi + for image in "$target"/images/*.tar; do load_image_archive "$image"; done; "$VERIFY_DIGESTS" "$target/manifest.json" compose "$target" up -d db redis; wait_healthy "$target" db; wait_healthy "$target" redis live=$(compose "$current" run --rm api alembic current 2>/dev/null | awk '/^[0-9a-f]+/ {print $1; exit}') @@ -21,7 +68,7 @@ head=$(compose "$current" run --rm api alembic heads 2>/dev/null | awk '/^[0-9a- compose "$target" run --rm api alembic upgrade head compose "$target" up -d; for _ in {1..36}; do curl -kfs https://localhost/version >/dev/null 2>&1 && break; sleep 5; done curl -kfsS https://localhost/version >/dev/null || { log_error "nginx/api did not become ready"; exit 1; } -hardware=$(manifest_value "$SAPOT_ROOT/shared/state.json" gsmHardwarePresent); ln -sfn "$target" "$SAPOT_ROOT/releases/current"; write_state upgrade "$current_version" "$version" "$hardware" +ln -sfn "$target" "$SAPOT_ROOT/releases/current"; write_state upgrade "$current_version" "$version" "$hardware" # Refresh the unit files only. An operator who deliberately disabled a timer # should not have an upgrade switch it back on, so nothing is enabled here. install_systemd_units "$target" From 237b00956ea98260638c69cadc9275b000003474 Mon Sep 17 00:00:00 2001 From: Adamskiee Date: Tue, 18 Aug 2026 11:31:28 +0800 Subject: [PATCH 3/3] chore(deploy-version): bump bundle to 0.1.0 --- deploy/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/VERSION b/deploy/VERSION index 5a5831ab..6e8bf73a 100644 --- a/deploy/VERSION +++ b/deploy/VERSION @@ -1 +1 @@ -0.0.7 +0.1.0