| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #!/usr/bin/env bash
- # 安装并本地联调测试:
- # 1. 构建并安装最新二进制到 /usr/local/bin/rtsp_multi_view
- # 2. 安装本地测试配置 /etc/rtsp_multi_view/channels_local.conf(若不存在)
- # 3. 临时停止系统服务(释放显示输出),用 PLC 模拟器跑若干 plc_sim 循环:
- # plc_server.py + plc_sim 写状态 + 已安装的 rtsp_multi_view 读布局,
- # 期间模拟一次 PLC 离线,验证右下角"PLC离线"报警与自动恢复
- # 4. 结束后自动恢复系统服务
- #
- # 用法: sudo ./install_local_test.sh [循环数] [每状态毫秒]
- # 循环数 plc_sim 完整循环次数(6 状态 x 间隔 = 1 循环),默认 1
- # 每状态毫秒 状态切换间隔,默认 5000
- # 环境变量: NO_OFFLINE=1 跳过 PLC 离线模拟
- set -u
- DIR="$(cd "$(dirname "$0")" && pwd)"
- cd "$DIR"
- BIN_SRC="$DIR/build/rtsp_multi_view"
- BIN_DST="/usr/local/bin/rtsp_multi_view"
- CONFIG_DIR="/etc/rtsp_multi_view"
- OUT="/tmp/opencode/install_local_test"
- CYCLE=1
- INTERVAL_MS=5000
- if [ $# -ge 1 ]; then CYCLE="$1"; fi
- if [ $# -ge 2 ]; then INTERVAL_MS="$2"; fi
- if [ "$CYCLE" -lt 1 ]; then CYCLE=1; fi
- if [ "$INTERVAL_MS" -lt 1000 ]; then INTERVAL_MS=1000; fi
- if [ "$EUID" -ne 0 ]; then
- echo "错误:请用 root 运行 (sudo ./install_local_test.sh)"
- exit 1
- fi
- PLCPID=""; SIMPID=""; VIEWPID=""
- SERVICE_ACTIVE=0
- stop_test_procs() {
- [ -n "$VIEWPID" ] && kill "$VIEWPID" 2>/dev/null
- [ -n "$SIMPID" ] && kill "$SIMPID" 2>/dev/null
- [ -n "$PLCPID" ] && kill "$PLCPID" 2>/dev/null
- sleep 1
- kill -9 "$VIEWPID" "$SIMPID" "$PLCPID" 2>/dev/null
- }
- cleanup() {
- stop_test_procs
- if [ "$SERVICE_ACTIVE" -eq 1 ]; then
- systemctl start rtsp_multi_view 2>/dev/null
- SERVICE_ACTIVE=0
- fi
- }
- trap cleanup EXIT INT TERM
- echo "== 构建 =="
- cmake --build "$DIR/build" -j"$(nproc)" || {
- echo "构建失败,请先运行 ./build.sh" >&2
- exit 1
- }
- echo "== 安装二进制 -> $BIN_DST =="
- cp "$BIN_SRC" "$BIN_DST"
- chmod +x "$BIN_DST"
- echo "== 安装本地测试配置 =="
- mkdir -p "$CONFIG_DIR"
- if [ ! -f "$CONFIG_DIR/channels_local.conf" ]; then
- cp "$DIR/channels_local.conf" "$CONFIG_DIR/channels_local.conf"
- echo "已创建 $CONFIG_DIR/channels_local.conf"
- else
- echo "已存在 $CONFIG_DIR/channels_local.conf(跳过)"
- fi
- if systemctl is-active --quiet rtsp_multi_view 2>/dev/null; then
- SERVICE_ACTIVE=1
- echo "== 临时停止系统服务 (rtsp_multi_view.service) =="
- systemctl stop rtsp_multi_view
- fi
- rm -rf "$OUT"; mkdir -p "$OUT"
- rm -f "$DIR/flog.txt"
- CONF="${CONF:-$DIR/channels_local.conf}"
- if ss -ltnp 2>/dev/null | grep -q ':102 '; then
- echo "错误:127.0.0.1:102 已被占用,无法启动本地 PLC:"
- ss -ltnp 2>/dev/null | grep ':102 '
- echo "请先释放端口(或 kill 占用进程)后重试。"
- exit 1
- fi
- echo "== 启动本地 PLC (plc_server.py :102) =="
- python3 "$DIR/plc_server.py" -p 102 >"$OUT/plcserver.log" 2>&1 &
- PLCPID=$!
- sleep 1
- if ! kill -0 "$PLCPID" 2>/dev/null || ! ss -ltnp 2>/dev/null | grep -q "pid=$PLCPID,"; then
- echo "错误:plc_server 启动失败,日志如下:"
- cat "$OUT/plcserver.log"
- exit 1
- fi
- echo "== 启动状态切换器 (plc_sim: ${CYCLE} 循环 x ${INTERVAL_MS}ms) =="
- "$DIR/build/plc_sim" -c "$CONF" -t "$INTERVAL_MS" >"$OUT/plcsim.log" 2>&1 &
- SIMPID=$!
- echo "== 启动已安装的主程序 ($BIN_DST) =="
- "$BIN_DST" -c "$CONF" >"$OUT/viewer.log" 2>&1 &
- VIEWPID=$!
- RUN_SEC=$(( CYCLE * 6 * INTERVAL_MS / 1000 + 10 ))
- OFF_SEC=$(( RUN_SEC / 2 > 8 ? RUN_SEC / 2 : 8 ))
- ONLINE_SEC=$(( OFF_SEC - 4 > 3 ? OFF_SEC - 4 : 3 ))
- echo "-- 等待 PLC 连通 (${ONLINE_SEC}s) --"
- sleep "$ONLINE_SEC"
- if [ "${NO_OFFLINE:-0}" != "1" ]; then
- echo "== 模拟 PLC 离线:杀掉 plc_server (${OFF_SEC}s) =="
- kill "$PLCPID" 2>/dev/null
- for _ in 1 2 3 4 5; do
- ss -ltnp 2>/dev/null | grep -q ':102 ' || break
- sleep 1
- done
- sleep "$OFF_SEC"
- echo "== 恢复 PLC =="
- python3 "$DIR/plc_server.py" -p 102 >>"$OUT/plcserver.log" 2>&1 &
- PLCPID=$!
- sleep 1
- if ! kill -0 "$PLCPID" 2>/dev/null || ! ss -ltnp 2>/dev/null | grep -q "pid=$PLCPID,"; then
- echo "错误:恢复 plc_server 失败,日志如下:"
- cat "$OUT/plcserver.log"
- exit 1
- fi
- fi
- echo "-- 跑完剩余时间 ($(( RUN_SEC - ONLINE_SEC - OFF_SEC ))s) --"
- sleep $(( RUN_SEC - ONLINE_SEC - OFF_SEC ))
- echo "== 停止本地测试进程 =="
- stop_test_procs
- if [ "$SERVICE_ACTIVE" -eq 1 ]; then
- echo "== 恢复系统服务 =="
- systemctl start rtsp_multi_view
- SERVICE_ACTIVE=0
- fi
- echo "==================== 结果 ===================="
- echo "--- PLC 报警/恢复 (flog.txt) ---"
- grep "PLC" "$DIR/flog.txt" 2>/dev/null || echo "(无 PLC 记录)"
- echo "--- plc_sim 状态循环 ---"
- grep -E "state [0-9]|connected" "$OUT/plcsim.log" | tail -20
- echo "--- viewer 异常 (排除常规超时重连) ---"
- grep -iE "error|fail|超时|失败" "$OUT/viewer.log" | grep -viE "连接失败: rtsp|Timeout waiting for first frame|connect 127.0.0.1:102 failed|recv failed" | head -10 || true
- echo "(done)"
- echo "完整日志: $OUT/"
- echo "生产服务: systemctl status rtsp_multi_view"
|