POSA_LEAKSMS/raspberry_pi_zero2w_display/install.sh
cw2007 42a6ee4bb0 feat(display): Zero 2 W ST7789 상태 디스플레이 노드
Pi Zero 2 W + ST7789 패널에 노드 상태(누수/온습도/미세먼지·오프라인·정체)를 상시 표시하는
디스플레이 노드 신설. 배포 전 렌더 검증 원칙에 따라 합성 최악 프레임 11종을 패널 실해상도로
render_preview/ 에 PNG 로 선렌더.

- st7789_driver.py · display_dashboard.py · render_preview.py(합성 프레임 생성)
- install.sh · vendor.sh · systemd/display-dashboard.service · 배선(WIRING)·연결테스트
- render_preview/01~11: 요약/통합/메트릭/오프라인/stale/legacy-무PM 최악 케이스
2026-07-19 10:47:00 +09:00

114 lines
4.1 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# 미니 상태 표시기 설치 (Pi Zero 2 W + ST7789V) — SPI 활성 + 패키지 + venv
# 대상 OS: Raspberry Pi OS Bookworm (64-bit)
#
# 폐쇄망: debs/ 또는 wheelhouse/ 가 있으면 자동 오프라인 모드(네트워크 0).
# 번들이 불완전하면 온라인 폴백 없이 명확히 중단(폐쇄망 규칙). OFFLINE=1/0 강제 가능.
# =============================================================================
set -euo pipefail
cd "$(dirname "$0")"
SERVICE_USER="${SERVICE_USER:-pi}"
echo "=========================================="
echo " 미니 상태 표시기 (ST7789V) 설치"
echo "=========================================="
if [ -r /proc/device-tree/model ]; then
MODEL="$(tr -d '\0' < /proc/device-tree/model)"
echo "[INFO] Board: ${MODEL}"
case "${MODEL}" in
*"Zero 2"*) : ;;
*) echo "[WARN] 이 폴더는 Pi Zero 2 W 용입니다 (다른 보드도 진행은 가능)." ;;
esac
fi
OFFLINE="${OFFLINE:-}"
if [ -z "${OFFLINE}" ]; then
if compgen -G "debs/*.deb" >/dev/null || [ -d wheelhouse ]; then
OFFLINE=1
echo "[INFO] 오프라인 번들 감지 → 폐쇄망 설치 모드(네트워크 없음)"
else
OFFLINE=0
echo "[INFO] 오프라인 번들 없음 → 온라인 설치 모드(인터넷 필요)"
fi
fi
# 1) 시스템 패키지: requests/Pillow/numpy/GPIO/spidev + 폰트
echo "[1/4] 시스템 패키지 설치..."
if [ "${OFFLINE}" = "1" ]; then
if ! compgen -G "debs/*.deb" >/dev/null; then
echo "[ERROR] 오프라인 모드인데 debs/ 가 비어 있습니다. vendor.sh 산출물을 넣고 재실행." >&2
exit 1
fi
sudo apt-get install -y --no-install-recommends --no-download ./debs/*.deb
else
sudo apt-get update
sudo apt-get install -y python3-requests python3-venv python3-pil python3-numpy \
python3-rpi.gpio python3-spidev fonts-dejavu-core
fi
# 2) SPI 활성화 (dtparam + 그룹)
echo "[2/4] SPI 활성화..."
BOOT_CFG=""
for c in /boot/firmware/config.txt /boot/config.txt; do
if [ -f "$c" ]; then BOOT_CFG="$c"; break; fi
done
if [ -n "${BOOT_CFG}" ]; then
if ! grep -q "^dtparam=spi=on" "${BOOT_CFG}"; then
echo " dtparam=spi=on 추가 (${BOOT_CFG}) — 재부팅 후 적용"
echo "dtparam=spi=on" | sudo tee -a "${BOOT_CFG}" >/dev/null
NEED_REBOOT=1
else
echo " dtparam=spi=on 이미 설정됨"
fi
else
echo "[WARN] config.txt 를 찾지 못함 — raspi-config 로 SPI 수동 활성화 필요"
fi
for grp in spi gpio; do
if getent group "$grp" >/dev/null 2>&1; then
sudo usermod -aG "$grp" "${SERVICE_USER}" || echo "[WARN] usermod $grp 실패"
fi
done
# 3) venv (+시스템 패키지 상속) + requests
echo "[3/4] Python venv..."
if [ ! -d venv ]; then
python3 -m venv --system-site-packages venv
fi
# shellcheck disable=SC1091
source venv/bin/activate
if [ "${OFFLINE}" = "1" ]; then
if [ ! -d wheelhouse ]; then
echo "[ERROR] 오프라인 모드인데 wheelhouse/ 가 없습니다. vendor.sh 산출물을 넣고 재실행." >&2
exit 1
fi
pip install --no-index --find-links=wheelhouse -r requirements.txt
else
pip install -r requirements.txt
fi
# 4) 로그 파일 + 설정 잠금
echo "[4/4] 로그·권한..."
sudo touch /var/log/display_dashboard.log
sudo chown "${SERVICE_USER}:${SERVICE_USER}" /var/log/display_dashboard.log || true
sudo chmod 640 /var/log/display_dashboard.log
if [ -f config_local.py ]; then
chmod 600 config_local.py
sudo chown "${SERVICE_USER}:${SERVICE_USER}" config_local.py 2>/dev/null || true
fi
if [ ! -f config_local.py ]; then
echo ""
echo "[!] config_local.py 가 없습니다: cp config_local.example.py config_local.py 후 실값 입력"
fi
echo ""
echo "=========================================="
echo " 설치 완료 (OFFLINE=${OFFLINE})"
echo "=========================================="
if [ "${NEED_REBOOT:-0}" = "1" ]; then
echo " ⚠️ SPI 방금 활성화 → 'sudo reboot' 후 화면이 동작합니다."
fi
echo " 단독 실행: source venv/bin/activate && python3 display_dashboard.py"
echo " 서비스 등록: README.md systemd 절 참고"