You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DroneDetector/capture_hourly.sh

228 lines
5.4 KiB
Bash

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -Eeuo pipefail
source .env
############################
# НАСТРОЙКИ
############################
# ЗАМЕНИ на реальную точку монтирования nvme1n1
BASE_DIR="/mnt/nvme1/dataset"
# Путь к python из venv
PYTHON_BIN="${PYTHON_BIN:-$PWD/.venv-sdr/bin/python}"
# Путь к headless скрипту
SCRIPT_PATH="${SCRIPT_PATH:-$PWD/scripts_nn/data_saver_headless.py}"
# Проверка, что каталог реально на nvme1n1
EXPECTED_DEVICE_PREFIX="/dev/nvme1n1"
# Лимиты
PER_FREQ_LIMIT_BYTES=$((3 * 1024 * 1024 * 1024)) # 3 GiB на частоту за запуск
TOTAL_LIMIT_BYTES=$((128 * 1024 * 1024 * 1024)) # общий лимит 512 GiB
CYCLE_SECONDS=36 # один цикл в час
# Параметры SDR
SAMP_RATE="20e6"
SPLIT_SIZE="400000"
DELAY="0.1"
RF_GAIN="12"
IF_GAIN="30"
BB_GAIN="36"
############################
# ЧАСТОТЫ И SERIAL ИЗ ENV
############################
ORDER=(433 750 915 1200 2400 3300 4500 5200 5800)
declare -A SERIAL
declare -A FREQ_HZ
SERIAL[433]="$hack_433"
FREQ_HZ[433]="433000000"
SERIAL[750]="$hack_750"
FREQ_HZ[750]="750000000"
SERIAL[868]="$hack_868"
FREQ_HZ[868]="868000000"
SERIAL[915]="$hack_915"
FREQ_HZ[915]="915000000"
SERIAL[1200]="$hack_1200"
FREQ_HZ[1200]="1200000000"
SERIAL[2400]="$hack_2400"
FREQ_HZ[2400]="2400000000"
SERIAL[3300]="$hack_3300"
FREQ_HZ[3300]="3300000000"
SERIAL[4500]="$hack_4500"
FREQ_HZ[4500]="4500000000"
SERIAL[5200]="$hack_5200"
FREQ_HZ[5200]="5200000000"
SERIAL[5800]="$hack_5800"
FREQ_HZ[5800]="5800000000"
############################
# ВСПОМОГАТЕЛЬНОЕ
############################
log() {
printf '[%s] %s\n' "$(date '+%F %T')" "$*"
}
dir_size_bytes() {
local path="$1"
if [[ -e "$path" ]]; then
du -sb "$path" 2>/dev/null | awk '{print $1}'
else
echo 0
fi
}
total_size_bytes() {
dir_size_bytes "$BASE_DIR"
}
ensure_requirements() {
if [[ ! -x "$PYTHON_BIN" ]]; then
echo "Не найден python: $PYTHON_BIN" >&2
exit 1
fi
if [[ ! -f "$SCRIPT_PATH" ]]; then
echo "Не найден script: $SCRIPT_PATH" >&2
exit 1
fi
mkdir -p "$BASE_DIR"
local dev
dev="$(df -P "$BASE_DIR" | awk 'NR==2 {print $1}')"
if [[ "$dev" != ${EXPECTED_DEVICE_PREFIX}* ]]; then
echo "BASE_DIR=$BASE_DIR сейчас находится на $dev, а ожидался ${EXPECTED_DEVICE_PREFIX}*" >&2
echo "Исправь BASE_DIR на точку монтирования nvme1n1" >&2
exit 1
fi
}
run_one_freq() {
local band="$1"
local serial="${SERIAL[$band]}"
local freq="${FREQ_HZ[$band]}"
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"
"$PYTHON_BIN" "$SCRIPT_PATH" \
--serial "$serial" \
--freq "$freq" \
--save-dir "$out_dir" \
--file-tag "${band}_" \
--samp-rate "$SAMP_RATE" \
--split-size "$SPLIT_SIZE" \
--delay "$DELAY" \
--rf-gain "$RF_GAIN" \
--if-gain "$IF_GAIN" \
--bb-gain "$BB_GAIN" \
>"$log_file" 2>&1 &
local pid=$!
log "PID=$pid"
while kill -0 "$pid" 2>/dev/null; do
local cur_dir_size cur_total_size
cur_dir_size="$(dir_size_bytes "$out_dir")"
cur_total_size="$(total_size_bytes)"
if (( cur_total_size >= TOTAL_LIMIT_BYTES )); then
log "Достигнут общий лимит 512 GiB. Останавливаю PID=$pid"
kill -TERM "$pid" 2>/dev/null || true
wait "$pid" 2>/dev/null || true
return 2
fi
if (( cur_dir_size >= PER_FREQ_LIMIT_BYTES )); then
log "Для band=$band достигнут лимит 3 GiB. Останавливаю PID=$pid"
kill -TERM "$pid" 2>/dev/null || true
for _ in {1..10}; do
if ! kill -0 "$pid" 2>/dev/null; then
break
fi
sleep 1
done
if kill -0 "$pid" 2>/dev/null; then
log "PID=$pid не завершился по TERM, отправляю KILL"
kill -KILL "$pid" 2>/dev/null || true
fi
wait "$pid" 2>/dev/null || true
break
fi
sleep 1
done
log "Завершен band=$band, размер=$(du -sh "$out_dir" | awk '{print $1}')"
return 0
}
main_loop() {
while true; do
local total_before cycle_start elapsed sleep_left
total_before="$(total_size_bytes)"
if (( total_before >= TOTAL_LIMIT_BYTES )); then
log "Общий размер уже >= 512 GiB, выхожу"
break
fi
cycle_start="$(date +%s)"
log "Новый цикл"
for band in "${ORDER[@]}"; do
if (( $(total_size_bytes) >= TOTAL_LIMIT_BYTES )); then
log "Общий лимит достигнут внутри цикла, выхожу"
return 0
fi
run_one_freq "$band" || {
rc=$?
if [[ $rc -eq 2 ]]; then
log "Остановка по общему лимиту"
return 0
fi
}
done
elapsed=$(( $(date +%s) - cycle_start ))
sleep_left=$(( CYCLE_SECONDS - elapsed ))
if (( sleep_left > 0 )); then
log "Цикл занял ${elapsed} сек, жду ${sleep_left} сек до следующего часа"
sleep "$sleep_left"
else
log "Цикл занял ${elapsed} сек, паузы нет"
fi
done
}
ensure_requirements
main_loop