#!/usr/bin/env bash # ============================================================================= # 온습도(SHT30) 모듈 v2 (Raspberry Pi 4 Model B) 설치 스크립트 — 2번 모듈 # 대상 OS: Raspberry Pi OS Bookworm (64-bit, aarch64) # # 폐쇄망(air-gapped) 지원: # - debs/ 또는 wheelhouse/ 가 있으면 자동으로 "오프라인 모드"로 전환. # - 오프라인 모드에서는 절대 네트워크에 접근하지 않는다. 번들이 일부만 있으면 # 온라인으로 몰래 빠지지 않고 명확한 오류로 중단한다(폐쇄망 규칙). 사전 # 다운로드는 vendor.sh 로 빌드 머신에서 수행. # - 환경변수 OFFLINE=1/0 으로 강제 지정 가능. # - 로그 파일 소유자: SERVICE_USER (기본 pi). # # 이 스크립트는 I2C 도 활성화한다(dtparam=i2c_arm=on + i2c-dev 로드 + i2c 그룹). # ============================================================================= set -euo pipefail cd "$(dirname "$0")" SERVICE_USER="${SERVICE_USER:-pi}" echo "==========================================" echo " 온습도(SHT30) 모듈 v2 (Pi 4) 설치 — 2번 모듈" echo "==========================================" # 0) 보드 모델 안내 (강제 아님) if [ -r /proc/device-tree/model ]; then MODEL="$(tr -d '\0' < /proc/device-tree/model)" echo "[INFO] 보드: ${MODEL}" case "${MODEL}" in *"Raspberry Pi 4"*) : ;; *) echo "[WARN] 이 폴더는 Raspberry Pi 4 Model B 전용입니다 (계속 진행은 가능)." ;; 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 + venv + i2c-tools echo "[1/4] 시스템 패키지 설치..." if [ "${OFFLINE}" = "1" ]; then if ! compgen -G "debs/*.deb" >/dev/null; then echo "[ERROR] 오프라인 모드인데 debs/ 가 비어있습니다. vendor.sh 산출물(debs/)을 이 폴더에 두고 재실행하세요." >&2 exit 1 fi echo " 오프라인 .deb 설치 (apt-get --no-download — 의존성 순서·해결 자동, 네트워크 미사용)" sudo apt-get install -y --no-download ./debs/*.deb else echo " 온라인 apt 설치 (인터넷 필요)" sudo apt-get update sudo apt-get install -y python3-requests python3-venv i2c-tools fi # 2) I2C 활성화 (dtparam + 모듈 로드 + 그룹) echo "[2/4] I2C 활성화..." # 부트 설정 경로: Bookworm=/boot/firmware/config.txt, 구버전=/boot/config.txt 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=i2c_arm=on" "${BOOT_CFG}"; then echo " ${BOOT_CFG} 에 dtparam=i2c_arm=on 추가 (재부팅 후 적용)" echo "dtparam=i2c_arm=on" | sudo tee -a "${BOOT_CFG}" >/dev/null NEED_REBOOT=1 else echo " dtparam=i2c_arm=on 이미 설정됨" fi else echo "[WARN] config.txt 를 찾지 못함 — raspi-config 로 수동 I2C 활성화 필요" fi # i2c-dev 모듈을 즉시 로드 + 부팅 시 자동 로드 등록 sudo modprobe i2c-dev 2>/dev/null || echo "[WARN] i2c-dev 즉시 로드 실패 (재부팅 후 적용될 수 있음)" if [ -d /etc/modules-load.d ] && ! grep -qrs "i2c-dev" /etc/modules-load.d/ 2>/dev/null; then echo "i2c-dev" | sudo tee /etc/modules-load.d/i2c.conf >/dev/null fi # 서비스 사용자를 i2c 그룹에 추가 (/dev/i2c-1 접근 권한) if getent group i2c >/dev/null 2>&1; then sudo usermod -aG i2c "${SERVICE_USER}" || echo "[WARN] usermod 실패 — SERVICE_USER=${SERVICE_USER} 확인" fi # 3) Python venv + requests + smbus2 echo "[3/4] Python 가상환경 설정..." if [ ! -d venv ]; then python3 -m venv --system-site-packages venv echo " venv 생성 완료" else echo " venv 이미 존재 — 건너뜀" fi # shellcheck disable=SC1091 source venv/bin/activate if [ "${OFFLINE}" = "1" ]; then if [ ! -d wheelhouse ]; then echo "[ERROR] 오프라인 모드인데 wheelhouse/ 가 없습니다. vendor.sh 산출물(wheelhouse/)을 두고 재실행하세요." >&2 exit 1 fi echo " 오프라인 wheel 설치 (--no-index — 네트워크 미사용)" pip install --no-index --find-links=wheelhouse -r requirements.txt else echo " 온라인 pip 설치 (인터넷 필요)" pip install --upgrade pip pip install -r requirements.txt fi echo " 패키지 설치 완료" # 4) 로그 파일 (최소 권한: 소유자만 쓰기) echo "[4/4] 로그 파일 생성..." sudo mkdir -p /var/log sudo touch /var/log/sht30_sensor.log if ! sudo chown "${SERVICE_USER}:${SERVICE_USER}" /var/log/sht30_sensor.log; then echo "[WARN] chown 실패 — SERVICE_USER=${SERVICE_USER} 존재 여부 확인" fi sudo chmod 640 /var/log/sht30_sensor.log # config_local 안내 (fail closed — 없으면 실행 시 즉시 중단됨) if [ ! -f config_local.py ]; then echo "" echo "[!] config_local.py 가 없습니다. 다음을 실행 후 실제 값으로 채우세요:" echo " cp config_local.example.py config_local.py" fi echo "" echo "==========================================" echo " 설치 완료! (OFFLINE=${OFFLINE})" echo "==========================================" if [ "${NEED_REBOOT:-0}" = "1" ]; then echo " ⚠️ I2C 를 방금 활성화했습니다 → 'sudo reboot' 후 센서가 인식됩니다." fi echo " 센서 확인: i2cdetect -y 1 (0x44 또는 0x45 가 보여야 함)" echo " 실행: source venv/bin/activate && python3 sht30_sensor.py" echo " 서비스: README.md 의 systemd 섹션 참고" echo ""