실제 배포는 Raspberry Pi 4(raspberry_pi4_sht30)인데 다수 문서가 STM32를 "현재 단일보드"로 서술하던 드리프트를 교정(README/SYSTEM_OVERVIEW/ DEPLOYMENT_PLAN은 이미 Pi 기준). - SHT30_SENSOR2_SETUP.md: Pi 기본 전면 재작성, STM32는 마이그레이션 대안 - README.md / wiring_diagram.md / INSTALL_PI_SERVER.md: Pi 기본으로 재구성 - ops_checks.php / security_evidence.php: /etc/sht30-sensor.env → config_local.py - api/sensor_data.php: 헤더 예시 device_id rpi4-sht30-01 - examples/*.html: device_id 교정 + 구식 env 예제 폐기 배너 - 전압 경고 정정: "5V=소자 손상"은 틀림(모듈 2.4~5.5V). Pi에서 3.3V 쓰는 이유는 Pi GPIO 3.3V 전용(5V 시 SDA/SCL 5V → Pi 손상)
124 lines
6.9 KiB
Markdown
124 lines
6.9 KiB
Markdown
# SHT30 온습도 센서 설치 가이드 (2번 모듈, sensor_id=2)
|
||
|
||
서버실 온습도 모니터링을 위해 Sensirion SHT30(한진데이터 P4422-3, I2C) 센서를 설치하고 서버에 연동하는 가이드입니다. **현재 배포 구성은 Raspberry Pi 4 Model B + Python**(`raspberry_pi4_sht30/` = `deploy/03_pi_b_sht30_id2/`, `device_id=rpi4-sht30-01`)입니다. STM32F407 펌웨어(`firmware/`)는 **별도의 마이그레이션 트랙**(하드웨어 미검증)으로, 실제 필드 배포와 무관합니다 — §3 참고.
|
||
|
||
> 기준 문서: 루트 [`README.md`](../README.md), [`SYSTEM_OVERVIEW.md`](../SYSTEM_OVERVIEW.md), [`docs/DEPLOYMENT_PLAN_RPI4x3.md`](./DEPLOYMENT_PLAN_RPI4x3.md) §5.
|
||
> 현장 인쇄용 배선·핀맵 도해: `deploy/03_pi_b_sht30_id2/WIRING.html` (브라우저로 열람 — 자체 완결형, 오프라인 가능).
|
||
|
||
## 1. 서버 준비
|
||
|
||
1. 웹 서버 DB에 통합 스키마를 적용합니다(신규 설치).
|
||
|
||
```sql
|
||
SOURCE sql/schema_sht30.sql;
|
||
```
|
||
|
||
2. 서버 파일을 배포합니다.
|
||
|
||
```text
|
||
php/api/sensor_data.php
|
||
php/dashboard.php
|
||
php/ops_checks.php
|
||
php/config.php
|
||
sql/schema_sht30.sql
|
||
```
|
||
|
||
API는 `sht30` 측정을 수신하면 `leak_sensor_status`를 갱신하고 측정값을 `leak_sensor_metric`에 저장합니다. 서버가 `METRIC_*` 임계로 고온/저온/고습/저습을 판정하고, 초과 시 종류별 30분 쿨다운으로 SMS를 발송합니다.
|
||
|
||
> 서버는 수집 시 `device_id`/`app_version`/`metric_type` 문자열을 **검증하지 않습니다**(HMAC 서명 + 필수필드 + `sensor_id` 범위 1..255 + 타임스탬프 신선도만 확인). 따라서 라즈베리파이 클라이언트(`rpi4-sht30-01`, `app_version=v2606-sht30-rpi4`)가 그대로 수용됩니다.
|
||
|
||
## 2. 기본 구성 — Raspberry Pi 4 (I2C)
|
||
|
||
소스: `deploy/03_pi_b_sht30_id2/`(= `raspberry_pi4_sht30/`). 근거는 해당 README.md, SETUP.md, WIRING.html, config.py, install.sh, systemd/sht30-sensor.service.
|
||
|
||
### 2.1 I2C 배선 (Pi 4 40핀 헤더, 버스 1)
|
||
|
||
상세 도해는 `deploy/03_pi_b_sht30_id2/WIRING.html`(SVG 핀맵 + 스키매틱 + 체크리스트)을 브라우저로 여십시오.
|
||
|
||
```text
|
||
SHT30 VCC -> Raspberry Pi 3.3V (물리 핀 1) ★ Pi 에서는 5V(핀 2·4) 금지 (모듈은 2.4~5.5V OK나, 5V 전원 시 SDA/SCL 5V → 3.3V 전용 Pi GPIO 손상)
|
||
SHT30 GND -> Raspberry Pi GND (핀 6; 대체 9·14·20·25·30·34·39)
|
||
SHT30 SDA -> Raspberry Pi GPIO2 / SDA1 (물리 핀 3) + 4.7kΩ 풀업 -> 3.3V
|
||
SHT30 SCL -> Raspberry Pi GPIO3 / SCL1 (물리 핀 5) + 4.7kΩ 풀업 -> 3.3V
|
||
SHT30 ADDR -> GND (주소 0x44; VDD면 0x45)
|
||
```
|
||
|
||
- 7-bit 주소 `0x44`(ADDR→GND). `config.py`의 `I2C_ADDR`와 반드시 일치.
|
||
- I2C 풀업 4.7kΩ ×2 — **SHT30 모듈에 온보드 풀업이 있으면 생략**.
|
||
- 명령 `0x2C06`(high-repeatability) → 약 20ms 대기 → 6바이트 read (드라이버 `sht30_driver.py`).
|
||
|
||
### 2.2 설정값 준비 (`config_local.py`)
|
||
|
||
```bash
|
||
cd /home/pi/raspberry_pi4_sht30
|
||
cp config_local.example.py config_local.py
|
||
# config_local.py 를 열어 채운다:
|
||
# API_URL = https://<서버>/raspi_leck_detecter/api/sensor_data.php (1번 모듈과 동일 엔드포인트)
|
||
# API_KEY = 서버 config.local.php 의 API_KEY 와 바이트 단위로 동일
|
||
# DEVICE_ID = rpi4-sht30-01
|
||
# DEVICE_LOCATION = 온습도 측정 위치(예: 서버실)
|
||
```
|
||
|
||
`config_local.py`가 없으면 실행 시 **명확한 오류로 즉시 중단**(fail closed)됩니다. `config_local.py`·`API_KEY`는 **절대 커밋하지 마세요**(`.gitignore` 처리됨). `sensor_id`(=2)/`sensor_name`은 `config.py` 기본값을 씁니다.
|
||
|
||
> ⚠️ 설정은 **Python `config_local.py`** 로만 합니다. 과거 문서에 있던 `/etc/sht30-sensor.env` 환경파일 방식은 이 라즈베리파이 모듈에서 **사용하지 않습니다**.
|
||
|
||
### 2.3 설치 (폐쇄망 오프라인 + 온라인 폴백)
|
||
|
||
원샷:
|
||
|
||
```bash
|
||
cd /home/pi/raspberry_pi4_sht30 && bash setup.sh # 설치→서비스 등록→검증→하드닝 (sudo 붙이지 말 것)
|
||
```
|
||
|
||
또는 단계별:
|
||
|
||
```bash
|
||
chmod +x install.sh && ./install.sh # apt(i2c-tools 등) + I2C 자동 활성화 + venv(requests/smbus2) + 로그
|
||
sudo reboot # I2C 를 새로 켠 경우 1회 (usermod -aG i2c 반영에도 필요)
|
||
```
|
||
|
||
- 폐쇄망: 인터넷 되는 **동일 aarch64** 머신에서 `./vendor.sh`로 `wheelhouse/`+`debs/` 번들 → 타깃 Pi로 복사 후 `./install.sh`(자동 오프라인).
|
||
|
||
### 2.4 systemd 자동 실행
|
||
|
||
```bash
|
||
sudo cp systemd/sht30-sensor.service /etc/systemd/system/
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now sht30-sensor
|
||
sudo systemctl status sht30-sensor
|
||
journalctl -u sht30-sensor -f
|
||
```
|
||
|
||
유닛 특성: `User=pi`, **`SupplementaryGroups=i2c`**(`/dev/i2c-1` 접근), `Restart=always`. `install.sh`는 유닛을 자동 설치하지 않으므로 이 단계 누락 금지.
|
||
|
||
### 2.5 동작 확인
|
||
|
||
```bash
|
||
i2cdetect -y 1 # 0x44(또는 0x45)가 보여야 함
|
||
source venv/bin/activate
|
||
python3 test_sensor.py # CRC/포맷 자가점검 + 측정 1회
|
||
python3 test_connection.py # 서명 POST 200(연결/서명), 403=API_KEY 불일치, 400=NTP/타임스탬프
|
||
```
|
||
|
||
> ⚠️ `test_sensor.py`는 하드웨어 없이도 **시뮬레이션으로 통과**합니다. 반드시 `i2cdetect`로 0x44를 먼저 확인하고, 서비스 로그에 시뮬레이션 WARN이 없는지 점검하세요(시뮬레이션 폴백이 배선 오류를 가릴 수 있음).
|
||
|
||
- Pi 시각은 **NTP 동기** 필수(서버 timestamp 신선도 ±600초 — Raspberry Pi OS 기본 활성).
|
||
- 이후 5분 주기 `periodic` 측정 보고.
|
||
|
||
## 3. 대안(계획) 구성 — STM32F407VGT6 (`sht30_fw`)
|
||
|
||
STM32F407 베어메탈 펌웨어(`firmware/`)는 RPi → STM32 전환을 목표로 한 **별도 마이그레이션 트랙**입니다. `docs/stm32f407_migration_plan.md` 기준 **코드는 완성되었으나 실제 보드 빌드·플래시·HIL 시험은 미검증**(서버 host/CA/API키/SNTP가 모두 placeholder)이며, 현재 필드에는 배포되어 있지 않습니다. 이 경로를 실제로 채택하려면 `firmware/docs/HARDWARE.md`·`firmware/docs/BUILD_OFFLINE.md`를 따라 하드웨어를 확정·검증해야 합니다.
|
||
|
||
- I2C1 배선(참고): SHT30 SCL → STM32 **PB6**(I2C1_SCL, AF4), SDA → **PB7**(I2C1_SDA, AF4), 각 4.7kΩ 풀업 → 3.3V, ADDR → GND(0x44). VCC는 **3.3V**(5V 금지).
|
||
- 보고 식별자: `device_id=stm32-sht30-01`, `app_version=v2606-sht30`, `sensor_id=2`. 서버는 이 문자열을 검증하지 않으므로 Pi/STM32 어느 쪽이든 유효 서명이면 동일하게 수용합니다.
|
||
|
||
## 4. 대시보드 결과
|
||
|
||
첫 정상 보고 후:
|
||
|
||
- `leak_sensor_status`에 `sensor_id=2` 항목이 생성됩니다.
|
||
- `leak_sensor_metric`에 온도/습도 이력이 누적됩니다.
|
||
- `dashboard.php`가 센서 카드에 최신 온도/습도와 임계 상태를 표시합니다.
|
||
|
||
장비가 `HEARTBEAT_TIMEOUT_SEC`(기본 1200초=20분)을 초과해 보고를 멈추면 서버가 오프라인으로 판정하고 SMS를 발송합니다.
|