|
|
|
|
@ -1,27 +1,37 @@
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -Eeuo pipefail
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
|
SCRIPT_OWNER="${CAPTURE_USER:-$(stat -c %U "$SCRIPT_DIR")}"
|
|
|
|
|
SCRIPT_OWNER_HOME="$(getent passwd "$SCRIPT_OWNER" | cut -d: -f6)"
|
|
|
|
|
cd "$SCRIPT_DIR"
|
|
|
|
|
|
|
|
|
|
source .env
|
|
|
|
|
source "$SCRIPT_DIR/.env"
|
|
|
|
|
############################
|
|
|
|
|
# НАСТРОЙКИ
|
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BASE_DIR="/home/sibsci/dataset/drone"
|
|
|
|
|
BASE_DIR="${CAPTURE_BASE_DIR:-${SCRIPT_OWNER_HOME}/dataset/noise}"
|
|
|
|
|
|
|
|
|
|
# Путь к python из venv
|
|
|
|
|
PYTHON_BIN="${PYTHON_BIN:-$PWD/.venv-sdr/bin/python}"
|
|
|
|
|
PYTHON_BIN="${PYTHON_BIN:-$SCRIPT_DIR/.venv-sdr/bin/python}"
|
|
|
|
|
|
|
|
|
|
# Путь к headless скрипту
|
|
|
|
|
SCRIPT_PATH="${SCRIPT_PATH:-$PWD/scripts_nn/data_saver_headless.py}"
|
|
|
|
|
SCRIPT_PATH="${SCRIPT_PATH:-$SCRIPT_DIR/scripts_nn/data_saver_headless.py}"
|
|
|
|
|
|
|
|
|
|
RUN_ONCE="${RUN_ONCE:-0}"
|
|
|
|
|
CAPTURE_LOG_FILE="${CAPTURE_LOG_FILE:-$BASE_DIR/capture_hourly.log}"
|
|
|
|
|
|
|
|
|
|
SYSTEMCTL_BIN=(systemctl)
|
|
|
|
|
CURRENT_CAPTURE_PID=""
|
|
|
|
|
CURRENT_SERVICE_UNIT=""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Лимиты
|
|
|
|
|
|
|
|
|
|
lim_all=70
|
|
|
|
|
PER_FREQ_LIMIT_BYTES=$((7 * 1024 * 1024 * 1024)) # GiB на частоту за запуск
|
|
|
|
|
lim_all=10
|
|
|
|
|
PER_FREQ_LIMIT_BYTES=$((1 * 1024 * 1024 * 1024)) # GiB на частоту за запуск
|
|
|
|
|
TOTAL_LIMIT_BYTES=$((lim_all * 1024 * 1024 * 1024)) # общий лимит GiB
|
|
|
|
|
CYCLE_SECONDS=1 # один цикл в час
|
|
|
|
|
|
|
|
|
|
@ -37,13 +47,12 @@ BB_GAIN="36"
|
|
|
|
|
# ЧАСТОТЫ И SERIAL ИЗ ENV
|
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
#ORDER=(433 750 915 1200 2400 3300 4500 5200 5800)
|
|
|
|
|
|
|
|
|
|
ORDER=(2400)
|
|
|
|
|
ORDER=(433)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
declare -A SERIAL
|
|
|
|
|
declare -A FREQ_HZ
|
|
|
|
|
declare -A SERVICE_UNIT
|
|
|
|
|
|
|
|
|
|
SERIAL[433]="$hack_433"
|
|
|
|
|
FREQ_HZ[433]="433000000"
|
|
|
|
|
@ -73,6 +82,16 @@ FREQ_HZ[5200]="5200000000"
|
|
|
|
|
SERIAL[5800]="$hack_5800"
|
|
|
|
|
FREQ_HZ[5800]="5800000000"
|
|
|
|
|
|
|
|
|
|
SERVICE_UNIT[433]="dronedetector-sdr-433.service"
|
|
|
|
|
SERVICE_UNIT[750]="dronedetector-sdr-750.service"
|
|
|
|
|
SERVICE_UNIT[915]="dronedetector-sdr-915.service"
|
|
|
|
|
SERVICE_UNIT[1200]="dronedetector-sdr-1200.service"
|
|
|
|
|
SERVICE_UNIT[2400]="dronedetector-sdr-2400.service"
|
|
|
|
|
SERVICE_UNIT[3300]="dronedetector-sdr-3300.service"
|
|
|
|
|
SERVICE_UNIT[4500]="dronedetector-sdr-4500.service"
|
|
|
|
|
SERVICE_UNIT[5200]="dronedetector-sdr-5200.service"
|
|
|
|
|
SERVICE_UNIT[5800]="dronedetector-sdr-5800.service"
|
|
|
|
|
|
|
|
|
|
############################
|
|
|
|
|
# ВСПОМОГАТЕЛЬНОЕ
|
|
|
|
|
############################
|
|
|
|
|
@ -81,6 +100,65 @@ log() {
|
|
|
|
|
printf '[%s] %s\n' "$(date '+%F %T')" "$*"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
systemctl_run() {
|
|
|
|
|
"${SYSTEMCTL_BIN[@]}" "$@"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
service_exists() {
|
|
|
|
|
local unit="$1"
|
|
|
|
|
systemctl_run show "$unit" >/dev/null 2>&1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stop_band_service() {
|
|
|
|
|
local band="$1"
|
|
|
|
|
local unit="${SERVICE_UNIT[$band]:-}"
|
|
|
|
|
|
|
|
|
|
if [[ -z "$unit" ]]; then
|
|
|
|
|
log "Для band=$band не найден service unit"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! service_exists "$unit"; then
|
|
|
|
|
log "Service unit $unit не установлен, пропускаю stop/start"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
log "Останавливаю service $unit перед записью band=$band"
|
|
|
|
|
systemctl_run stop "$unit"
|
|
|
|
|
CURRENT_SERVICE_UNIT="$unit"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start_current_service() {
|
|
|
|
|
if [[ -z "$CURRENT_SERVICE_UNIT" ]]; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
log "Запускаю service $CURRENT_SERVICE_UNIT после записи"
|
|
|
|
|
systemctl_run start "$CURRENT_SERVICE_UNIT"
|
|
|
|
|
CURRENT_SERVICE_UNIT=""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cleanup_capture() {
|
|
|
|
|
if [[ -n "$CURRENT_CAPTURE_PID" ]] && kill -0 "$CURRENT_CAPTURE_PID" 2>/dev/null; then
|
|
|
|
|
log "Останавливаю текущий PID=$CURRENT_CAPTURE_PID при завершении скрипта"
|
|
|
|
|
kill -TERM "$CURRENT_CAPTURE_PID" 2>/dev/null || true
|
|
|
|
|
wait "$CURRENT_CAPTURE_PID" 2>/dev/null || true
|
|
|
|
|
fi
|
|
|
|
|
CURRENT_CAPTURE_PID=""
|
|
|
|
|
|
|
|
|
|
if [[ -n "$CURRENT_SERVICE_UNIT" ]]; then
|
|
|
|
|
log "Восстанавливаю service $CURRENT_SERVICE_UNIT при завершении скрипта"
|
|
|
|
|
systemctl_run start "$CURRENT_SERVICE_UNIT" || true
|
|
|
|
|
CURRENT_SERVICE_UNIT=""
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
on_signal() {
|
|
|
|
|
local sig="$1"
|
|
|
|
|
log "Получен сигнал $sig, завершаю работу"
|
|
|
|
|
exit 130
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir_size_bytes() {
|
|
|
|
|
local path="$1"
|
|
|
|
|
if [[ -e "$path" ]]; then
|
|
|
|
|
@ -105,7 +183,40 @@ ensure_requirements() {
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! command -v systemctl >/dev/null 2>&1; then
|
|
|
|
|
echo "Не найден systemctl" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
|
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
|
|
|
SYSTEMCTL_BIN=(sudo systemctl)
|
|
|
|
|
else
|
|
|
|
|
echo "Для управления service нужен root или sudo" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
mkdir -p "$BASE_DIR"
|
|
|
|
|
mkdir -p "$(dirname "$CAPTURE_LOG_FILE")"
|
|
|
|
|
|
|
|
|
|
if [[ -n "${CAPTURE_ORDER:-}" ]]; then
|
|
|
|
|
ORDER=()
|
|
|
|
|
local band
|
|
|
|
|
for band in ${CAPTURE_ORDER//,/ }; do
|
|
|
|
|
ORDER+=("$band")
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ "${#ORDER[@]}" -eq 0 ]]; then
|
|
|
|
|
echo "ORDER пустой. Укажите частоты в ORDER или задайте CAPTURE_ORDER." >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
log "Рабочая директория: $SCRIPT_DIR"
|
|
|
|
|
log "BASE_DIR: $BASE_DIR"
|
|
|
|
|
log "ORDER: ${ORDER[*]}"
|
|
|
|
|
log "RUN_ONCE: $RUN_ONCE"
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -114,14 +225,23 @@ run_one_freq() {
|
|
|
|
|
local serial="${SERIAL[$band]}"
|
|
|
|
|
local freq="${FREQ_HZ[$band]}"
|
|
|
|
|
|
|
|
|
|
if [[ -z "$serial" ]]; then
|
|
|
|
|
log "Для band=$band пустой serial, пропускаю"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local ts out_dir log_file
|
|
|
|
|
ts="$(date '+%F_%H-%M-%S')"
|
|
|
|
|
out_dir="$BASE_DIR/$band/$ts"
|
|
|
|
|
log_file="$out_dir/run.log"
|
|
|
|
|
|
|
|
|
|
mkdir -p "$out_dir"
|
|
|
|
|
|
|
|
|
|
log "Старт band=$band serial=$serial freq=$freq dir=$out_dir"
|
|
|
|
|
if ! mkdir -p "$out_dir"; then
|
|
|
|
|
log "Не удалось создать каталог $out_dir"
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
stop_band_service "$band"
|
|
|
|
|
|
|
|
|
|
"$PYTHON_BIN" "$SCRIPT_PATH" \
|
|
|
|
|
--serial "$serial" \
|
|
|
|
|
@ -137,6 +257,7 @@ run_one_freq() {
|
|
|
|
|
>"$log_file" 2>&1 &
|
|
|
|
|
|
|
|
|
|
local pid=$!
|
|
|
|
|
CURRENT_CAPTURE_PID="$pid"
|
|
|
|
|
log "PID=$pid"
|
|
|
|
|
|
|
|
|
|
while kill -0 "$pid" 2>/dev/null; do
|
|
|
|
|
@ -148,6 +269,8 @@ run_one_freq() {
|
|
|
|
|
log "Достигнут общий лимит $lim_all GiB. Останавливаю PID=$pid"
|
|
|
|
|
kill -TERM "$pid" 2>/dev/null || true
|
|
|
|
|
wait "$pid" 2>/dev/null || true
|
|
|
|
|
CURRENT_CAPTURE_PID=""
|
|
|
|
|
start_current_service
|
|
|
|
|
return 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
@ -174,6 +297,8 @@ run_one_freq() {
|
|
|
|
|
sleep 1
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
CURRENT_CAPTURE_PID=""
|
|
|
|
|
start_current_service
|
|
|
|
|
log "Завершен band=$band, размер=$(du -sh "$out_dir" | awk '{print $1}')"
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
@ -202,10 +327,18 @@ main_loop() {
|
|
|
|
|
if [[ $rc -eq 2 ]]; then
|
|
|
|
|
log "Остановка по общему лимиту"
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
log "Ошибка записи band=$band rc=$rc"
|
|
|
|
|
return "$rc"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [[ "$RUN_ONCE" == "1" ]]; then
|
|
|
|
|
log "RUN_ONCE=1, завершаю работу после одного цикла"
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
elapsed=$(( $(date +%s) - cycle_start ))
|
|
|
|
|
sleep_left=$(( CYCLE_SECONDS - elapsed ))
|
|
|
|
|
|
|
|
|
|
@ -218,5 +351,9 @@ main_loop() {
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trap cleanup_capture EXIT
|
|
|
|
|
trap 'on_signal INT' INT
|
|
|
|
|
trap 'on_signal TERM' TERM
|
|
|
|
|
|
|
|
|
|
ensure_requirements
|
|
|
|
|
main_loop
|
|
|
|
|
main_loop
|
|
|
|
|
|