# 서버실 온습도(SHT30) 모니터링 시스템 v2606 정리 보고서 ## 개요 본 시스템은 서버실 온습도를 24시간 감시하고, 임계 초과(고온/저온/고습/저습)·정상복귀·장비 오프라인/복구 상황을 SMS와 웹 대시보드로 알리는 IoT 기반 모니터링 체계입니다. Sensirion SHT30 센서가 5분 주기로 온습도를 측정하면, STM32F407VGT6 펌웨어가 유선 Ethernet/TLS로 서버에 보고하고, 서버가 임계를 판정해 통보합니다. ## 시스템 구성 > **단일 보드 온습도 전용**: 메인 MCU는 STM32F407VGT6(Cortex-M4F) 베어메탈 펌웨어이며, > 연결은 유선 Ethernet(LAN8720 RMII) + 온칩 TLS(mbedTLS HTTPS)입니다. 단일 보드 > `sht30_fw`(`sensor_id=2`, `device_id=stm32-sht30-01`)만 사용합니다. 펌웨어는 `firmware/`, > 하드웨어 핀맵은 `firmware/docs/HARDWARE.md`를 참조합니다. ```text [SHT30] --I2C(0x44)--> [STM32F407VGT6 (sht30_fw)] --유선 Ethernet/TLS--> [Cafe24 PHP API] | [MySQL DB] | [SMS 발송 / 대시보드] ``` > 인증: 펌웨어는 `X-Signature: sha256(API_KEY + 요청본문)`(raw-body) 헤더로 서명하며, > 서버는 이 서명을 검증합니다. 온습도 임계 판정은 모두 서버(`php/config.php` `METRIC_*` > 상수 + `api/sensor_data.php`)에서 수행하므로, 폐쇄망에서 임계값 변경 시 서버 설정만 > 바꾸면 되고 펌웨어 재플래시가 필요하지 않습니다. ## 측정·임계 - 측정 주기: 5분(펌웨어 `APP_SHT30_REPORT_INTERVAL_SEC=300`). 최초 1회 startup, 이후 periodic. - 명령 `0x2C06`(high-repeatability) → 약 20ms 대기 → 6바이트 read → 온도(℃)/상대습도(%) 변환. - 임계(서버 판정, `METRIC_*`; `config.local.php` override): - 고온 30℃ / 저온 10℃ / 고습 70% / 저습 20% - 복귀 히스테리시스 ±1℃ · ±3% - 동일 종류 경보 쿨다운 1800초(30분) ## 이벤트 / SMS 정책 | 이벤트 | 조건 | DB | SMS | |---|---|---|---| | `startup` | 기기 시작 첫 측정 | `sensor_log` | X | | `periodic` | 정상 주기 측정(5분) | `sensor_metric` | X | | 고온/저온/고습/저습 경보 | 측정값이 임계 초과 | `sensor_metric.metric_status` | O (종류별 30분 쿨다운) | | 정상복귀 | 경보 후 히스테리시스 포함 정상 회복 | `sensor_metric` | O (1회) | | 장비 오프라인 | 마지막 수신 후 `HEARTBEAT_TIMEOUT_SEC`(기본 1200초=20분) 초과 | `sensor_status` | O | | 장비 복구 | 오프라인 후 재수신 | `sensor_status` | O | ## 운영 정책 | 항목 | v2606 기준 | |---|---| | 측정 주기 | 5분(펌웨어 300초) | | 임계 판정 | 서버(`METRIC_*`), 폐쇄망에서 설정 변경으로 조정 | | 고온/저온/고습/저습 SMS | 임계 초과 시 발송, 종류별 30분 쿨다운 | | 정상복귀 SMS | 히스테리시스 포함 회복 시 1회 | | 장비 오프라인 | 마지막 수신 후 1200초(20분) 초과 시 알림 | | 오프라인 체크 | `cron_heartbeat.php` 주기 실행 | | 운영 자가진단 | 설정값, 필수 테이블(`sensor_metric`), 권한, SMS 실패 표시 | | 운영 요약 | 30일 경보/복귀/오프라인, SMS 현황 | | 설치 점검 | DB/마이그레이션/권한/SMS 테스트 | | 월간 보고서 | 월별 임계 경보/복귀/오프라인/SMS 현황 CSV 및 인쇄 출력 | ## DB 구성 - 신규 설치: `sql/schema_sht30.sql` 하나(테이블 `sensor_log`, `sensor_status`, `sensor_metric`, `sms_log`). - 기존 누수 설치 전환: `sql/migration_drop_leak.sql`(레거시 누수 컬럼/테이블 정리, `sensor_metric` 보장). ## 백업 위치 정리 전 원본은 아래 폴더에 보관했습니다. ```text _backup/pre_v2605_20260519/ ``` ## 남은 운영 작업 ### 서버 (PHP/DB) 1. 운영 서버의 실제 DB/SMS/API 키를 새 값으로 교체합니다. 2. `php/config.local.example.php`를 기준으로 운영 서버에 `config.local.php`를 만듭니다(온습도 임계 `METRIC_*` 확인). 3. 신규 DB에는 `schema_sht30.sql`을 실행합니다. 기존 누수 설치는 `migration_drop_leak.sql`로 전환합니다. 4. `cron_heartbeat.php`를 1분 간격 cron으로 등록합니다. ### 펌웨어 (STM32F407) — `firmware/docs/` 참조 5. `firmware/common/secrets.h`를 `secrets.h.example`에서 생성하고 `APP_API_KEY`를 서버 `API_KEY`와 동일하게 설정합니다. 6. `firmware/certs/server_ca.c`의 자리표시자 CA를 실제 Cafe24 루트 CA로 교체합니다(`firmware/certs/README.md`). 7. `firmware/common/app_config.h`의 `APP_API_HOST`/`APP_API_PATH`와 네트워크 주소(DHCP/static), `APP_SHT30_I2C_ADDR`(0x44), `APP_SHT30_REPORT_INTERVAL_SEC`(300)을 운영 값으로 설정합니다. 8. 폐쇄망 빌드 머신에서 의존성을 벤더링한 뒤 `sht30_fw`를 빌드·플래시합니다(`firmware/docs/BUILD_OFFLINE.md`). 9. **하드웨어 확정 필요(TODO(hw))**: LAN8720 PHY 주소·REF_CLK 소스, RTC 클럭원(LSE/LSI), HSE 주파수, 상태 LED 핀. 상세는 `firmware/docs/HARDWARE.md`. SHT30 I2C는 PB6/PB7, 0x44, 4.7kΩ 풀업으로 확정. 10. 첫 부팅 후 USART3(PD8/PD9, 115200) 콘솔 로그로 I2C 측정/네트워크/SNTP/TLS 핸드셰이크/서버 200 응답을 확인합니다.