- Updated argument parsing in manage_api.py to include new threshold parameters. - Enhanced _config_payload to include thresholds and webhook configurations. - Modified _build_summary to track queue metrics and adjust alert reporting. - Refactored DwellEngine to utilize queue thresholds for alerting and reporting. - Added queue metrics calculations and status change tracking in dwell_engine.py. - Updated notifier.py to support posting JSON events to webhooks. - Adjusted example configuration to reflect new threshold parameters. - Enhanced Docker entrypoint script for better process management. - Updated tests to cover new queue metrics and thresholds. - Improved ManagedServiceDetail and ManagedServices Vue components to display queue metrics.
104 lines
2.7 KiB
Bash
Executable File
104 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
set -eu
|
|
|
|
PROJECT_DIR="/opt/people-flow"
|
|
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
|
|
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
|
|
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
|
|
RTSP_URL="${RTSP_URL:-}"
|
|
API_HOST="${API_HOST:-0.0.0.0}"
|
|
API_PORT="${API_PORT:-18082}"
|
|
|
|
mkdir -p "${OUTPUT_DIR}" "$(dirname "${CONFIG_PATH}")"
|
|
|
|
if [ ! -f "${CONFIG_PATH}" ]; then
|
|
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
|
|
fi
|
|
|
|
python - "$CONFIG_PATH" "$RTSP_URL" "$OUTPUT_DIR" <<'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
import yaml
|
|
|
|
config_path = Path(sys.argv[1])
|
|
rtsp_url = sys.argv[2]
|
|
output_dir = sys.argv[3]
|
|
|
|
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
|
runtime = raw.setdefault("runtime", {})
|
|
if rtsp_url:
|
|
runtime["rtsp_url"] = rtsp_url
|
|
runtime["output_dir"] = output_dir
|
|
yolo = raw.setdefault("yolo", {})
|
|
yolo.setdefault("model_path", "weights/yolo11n.pt")
|
|
config_path.write_text(
|
|
yaml.safe_dump(raw, allow_unicode=True, sort_keys=False),
|
|
encoding="utf-8",
|
|
)
|
|
PY
|
|
|
|
exec python - "$CONFIG_PATH" "$API_HOST" "$API_PORT" <<'PY'
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
config_path, api_host, api_port = sys.argv[1:4]
|
|
commands = [
|
|
[sys.executable, "main.py", "--config", config_path, "rtsp"],
|
|
[
|
|
sys.executable,
|
|
"main.py",
|
|
"--config",
|
|
config_path,
|
|
"manage-api",
|
|
"--host",
|
|
api_host,
|
|
"--port",
|
|
api_port,
|
|
],
|
|
]
|
|
processes = [subprocess.Popen(command) for command in commands]
|
|
|
|
|
|
def terminate_all(signum, _frame):
|
|
for process in processes:
|
|
if process.poll() is None:
|
|
process.terminate()
|
|
deadline = time.time() + 10
|
|
for process in processes:
|
|
if process.poll() is not None:
|
|
continue
|
|
timeout = max(0, deadline - time.time())
|
|
try:
|
|
process.wait(timeout=timeout)
|
|
except subprocess.TimeoutExpired:
|
|
process.kill()
|
|
raise SystemExit(128 + signum)
|
|
|
|
|
|
for handled_signal in (signal.SIGINT, signal.SIGTERM):
|
|
signal.signal(handled_signal, terminate_all)
|
|
|
|
while True:
|
|
for index, process in enumerate(processes):
|
|
return_code = process.poll()
|
|
if return_code is None:
|
|
continue
|
|
for other_index, other_process in enumerate(processes):
|
|
if other_index == index or other_process.poll() is not None:
|
|
continue
|
|
other_process.terminate()
|
|
deadline = time.time() + 10
|
|
for other_index, other_process in enumerate(processes):
|
|
if other_index == index or other_process.poll() is not None:
|
|
continue
|
|
timeout = max(0, deadline - time.time())
|
|
try:
|
|
other_process.wait(timeout=timeout)
|
|
except subprocess.TimeoutExpired:
|
|
other_process.kill()
|
|
raise SystemExit(return_code)
|
|
time.sleep(0.5)
|
|
PY
|