telemetry-dashboard/scripts/demo-stack.sh
2026-07-04 04:18:36 +09:00

159 lines
6 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Boot the side-by-side demo: one synthetic ground station feeding BOTH UIs
# through the real Django backend (production topology).
#
# test_server.py --push ──▶ Django :8000 ──▶ leaflet_svelte :5173 (/track)
# └──▶ telemetry-dashboard :5174
#
# The station flies along mock_prediction.json (the real predict) with a
# bounded random drift, if that file exists at the repo root.
#
# Adapted from leaflet_svelte/scripts/run-stack.sh (paths updated after the
# repo move; DJANGO_ENV is NOT set so Django uses the local sqlite db).
#
# Usage:
# scripts/demo-stack.sh # start everything
# scripts/demo-stack.sh restart-flight # начать полёт заново (станция + чистка истории)
# scripts/demo-stack.sh stop # stop everything
set -euo pipefail
ROOT=/home/anton/stratoflights
BACKEND_DIR=$ROOT/stratoflights
LEAFLET_DIR=$ROOT/leaflet_svelte
DASH_DIR=$ROOT/telemetry-dashboard
TRAJECTORY=$ROOT/mock_prediction.json
PID_DIR=/tmp/strato-demo
SPEEDUP=${SPEEDUP:-20}
provision() { # prints "SAT TOKEN"
(cd "$BACKEND_DIR" && python3 - <<'EOF'
import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'stratoflights.settings')
django.setup()
from stratoflights_api.models import Satellite, User
from rest_framework.authtoken.models import Token
u = User.objects.get(username='demo')
sat, _ = Satellite.objects.get_or_create(name='demo-balloon', user=u)
u.satellites.add(sat)
token, _ = Token.objects.get_or_create(user=u)
print(sat.id, token.key)
EOF
)
}
wipe_history() {
(cd "$BACKEND_DIR" && python3 - <<'EOF'
import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'stratoflights.settings')
django.setup()
from stratoflights_api.models import TelemetryPacket
n, _ = TelemetryPacket.objects.filter(satellite__name='demo-balloon').delete()
print(f"история очищена: {n} пакетов")
EOF
)
}
kill_station() {
pkill -f 'test_server.py --push' 2>/dev/null && sleep 1 || true
rm -f "$PID_DIR/station.pid"
}
start_station() { # $1=SAT $2=TOKEN
local traj_args=()
[[ -f "$TRAJECTORY" ]] && traj_args=(--trajectory "$TRAJECTORY")
echo "starting synthetic ground station (speedup x$SPEEDUP)"
cd "$DASH_DIR"
python3 -u test_server.py --push ws://localhost:8000 \
--satellite "$1" --token "$2" \
--interval 1 --speedup "$SPEEDUP" "${traj_args[@]}" \
> /tmp/strato-demo-station.log 2>&1 &
echo $! > "$PID_DIR/station.pid"
}
case "${1:-}" in
stop)
for f in "$PID_DIR"/*.pid; do
[[ -f "$f" ]] && kill "$(cat "$f")" 2>/dev/null && echo "stopped $(basename "$f" .pid)"
rm -f "$f"
done
exit 0
;;
restart-flight)
mkdir -p "$PID_DIR"
kill_station
wipe_history
read -r SAT TOKEN < <(provision)
start_station "$SAT" "$TOKEN"
echo "полёт перезапущен с нуля. Нажми Отключиться/Подключиться в обоих окнах,"
echo "чтобы сбросить старые графики (история в БД уже чистая)."
exit 0
;;
esac
mkdir -p "$PID_DIR"
# --- fake predictor on :8080 (TawhiriClient's hardcoded port) ------------------
# Serves the mock_prediction trajectory, so «Запустить прогноз» in leaflet
# returns exactly the flight the demo station is flying.
if ! ss -tlnp 2>/dev/null | grep -q ':8080'; then
echo "starting fake predictor on :8080"
FAKE_TAWHIRI_TRAJECTORY="$TRAJECTORY" \
python3 -u "$LEAFLET_DIR/tests/e2e/fake_tawhiri.py" 8080 \
> /tmp/strato-demo-predictor.log 2>&1 &
echo $! > "$PID_DIR/predictor.pid"
fi
# --- Django (sqlite dev settings) --------------------------------------------
# Restart if it's ours (pid file) so env changes (CSRF origins) apply.
if [[ -f "$PID_DIR/django.pid" ]] && kill -0 "$(cat "$PID_DIR/django.pid")" 2>/dev/null; then
kill "$(cat "$PID_DIR/django.pid")" 2>/dev/null || true
sleep 1
fi
if ! ss -tlnp 2>/dev/null | grep -q ':8000'; then
echo "starting Django on :8000"
cd "$BACKEND_DIR"
DEBUG=True \
ALLOWED_HOSTS=localhost,127.0.0.1 \
CSRF_TRUSTED_ORIGINS="http://localhost:5173,http://localhost:5174,http://localhost:8000,http://127.0.0.1:5173,http://127.0.0.1:5174,http://127.0.0.1:8000" \
python3 manage.py runserver 0.0.0.0:8000 > /tmp/strato-demo-django.log 2>&1 &
echo $! > "$PID_DIR/django.pid"
sleep 3
else
echo "ВНИМАНИЕ: :8000 занят не нашим Django — если ловишь CSRF-ошибку, останови его и перезапусти этот скрипт"
fi
read -r SAT TOKEN < <(provision)
# --- synthetic ground station (push mode) -------------------------------------
# всегда стартуем полёт с нуля: старую станцию гасим, историю чистим
kill_station
wipe_history
start_station "$SAT" "$TOKEN"
# --- leaflet_svelte -----------------------------------------------------------
if ! ss -tlnp 2>/dev/null | grep -q ':5173'; then
echo "starting leaflet_svelte on :5173"
cd "$LEAFLET_DIR"
VITE_USE_MOCK_API=false VITE_API_BASE_URL=/api VITE_API_PROXY_TARGET=http://localhost:8000 \
npm run dev -- --port 5173 --strictPort > /tmp/strato-demo-leaflet.log 2>&1 &
echo $! > "$PID_DIR/leaflet.pid"
fi
# --- telemetry-dashboard ------------------------------------------------------
if ! ss -tlnp 2>/dev/null | grep -q ':5174'; then
echo "starting telemetry-dashboard on :5174"
cd "$DASH_DIR"
VITE_DEFAULT_WS_URL="ws://localhost:8000/api/ws/satellite/$SAT/telemetry/" \
npm run dev -- --port 5174 --strictPort > /tmp/strato-demo-dash.log 2>&1 &
echo $! > "$PID_DIR/dash.pid"
fi
sleep 2
echo
echo "--- demo stack ready ---"
echo " satellite UUID: $SAT"
echo " leaflet (карта): http://localhost:5173/track (login: demo/demo, ID спутника выше)"
echo " дэшборд (приборы): http://localhost:5174/ (ws://localhost:8000/api/ws/satellite/$SAT/telemetry/)"
echo
echo "перезапуск полёта: scripts/demo-stack.sh restart-flight"
echo "logs: /tmp/strato-demo-*.log stop: scripts/demo-stack.sh stop"