# Control 팬 제어, 시스템 모니터링, WiFi 제어, WakeLock, Web Push 알림을 제공하는 PHP 기반 단일 관리 패널입니다. ## 프로젝트 성격 Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를 웹에서 관리하기 위한 내부 운영 도구입니다. 로그인 후 대시보드에서 온도, 팬 RPM, PWM, WiFi client, 배터리, notice, dmesg, process 후보, Push 구독 상태를 확인하고 필요한 제어 명령을 실행합니다. 상태 갱신은 WebSocket을 우선 사용하고, 연결 실패 시 HTTP fallback으로 전환합니다. 팬 정책 적용과 센서 수집은 백그라운드 작업과 API 호출을 통해 DB에 기록됩니다. ## 주요 기능 - 팬 모드 `auto`, `manual`, `off` 제어 - PWM slider 기반 수동 팬 제어 - CPU/RP1 온도, 팬 RPM, 팬 효율, CPU 전력, 배터리 상태 차트 - WiFi client 목록과 2.4G/5G client 수 표시 - WiFi client 상태 표시 - System Notice와 process CPU/MEM 후보 표시 - dmesg 로그 열람 - Web Push 구독 등록, 자동 복구, 구독 기기 목록 표시 - Push 기기 건강 상태 추적과 헬스체크 수동/자동 실행 - WakeLock 버튼으로 대시보드 화면 꺼짐 방지 ## 주요 API - `public/api.php?action=status`: 팬, 센서, 시스템, WiFi, history, notice 상태 조회 - `public/api.php?action=collect`: 센서 snapshot 수집 후 팬 정책 적용 - `public/api.php?action=fan`: 팬 모드와 PWM 저장/적용 - `public/api.php?action=wifi`: 허용된 WiFi/DHCP service 제어 - `public/api.php?action=push_devices`: Push 구독 기기 목록 조회 - `public/api.php?action=push_status`: 브라우저 구독 endpoint의 서버 등록 상태 조회 - `public/api.php?action=send_push_healthcheck`: 등록된 Push 기기 전체에 상태 확인 알림 발송 - `public/api.php?action=delete_push_endpoint`: 현재 endpoint 구독 삭제 - `public/api.php?action=dmesg`: dmesg 로그 조회 ## 구성 - `public/index.php`: 로그인과 관리 화면 - `public/api.php`: 상태 조회와 조작 API - `public/assets/app.js`: 대시보드 렌더링, WebSocket, 차트, 조작 이벤트 - `public/assets/wakelock.js`: Screen Wake Lock API 제어 - `public/push_subscribe.js`: Push 구독 등록, 삭제, 자동 복구 - `public/sw.js`: Push service worker - `config/config.php`: DB, 인증, CSRF, Push, shell 실행 공통 함수 - `config/vapid.php`: 외부 secret 기반 VAPID 설정 bridge - `apply_policy.php`: CLI/cron 팬 정책 적용 - `bin/control_ws.php`: WebSocket 서버 - `bin/push_healthcheck.php`: 작업스케줄러용 Push 헬스체크 CLI ## 데이터/저장소 - `control_state`: 팬 모드와 PWM 상태 - `sensor_logs`: 온도, RPM, PWM, 배터리, load, memory, disk, uptime - `system_notice_state`: notice 활성 상태와 기준값 - `system_notice_logs`: notice 발생 이력 - `push_subscriptions`: Web Push 구독 정보 - `push_event_logs`: Push 발송, 수신, 표시, 클릭, 실패 이벤트 - `/home/seo/secret/control.php`: 앱 비밀번호, DB 설정, VAPID key ## Push 누락 방지 구조 Control은 숨은 알림을 반복 발송하는 방식 대신 구독 자동 복구, 실제 수신 이벤트 기록, 발송 실패 추적, 저빈도 헬스체크를 조합합니다. ### 클라이언트 자동 복구 - 대시보드 로드 직후 Push 구독 상태를 확인합니다. - 화면이 다시 보일 때 구독 상태를 재확인합니다. - 5분마다 브라우저 구독과 서버 등록 상태를 비교합니다. - 브라우저 구독이 없으면 VAPID 공개키로 재구독합니다. - 브라우저 구독은 있으나 서버에 누락되어 있으면 다시 저장합니다. ### 서버 상태 추적 `push_subscriptions`에는 구독 정보와 함께 다음 상태가 저장됩니다. - `last_send_success_at`: 서버가 endpoint로 Push 발송에 성공한 시간 - `last_send_failed_at`: 서버 발송 실패 시간 - `last_received_at`: Service Worker가 `push` 이벤트를 실제 수신한 시간 - `last_notification_at`: 알림 표시 성공 시간 - `last_click_at`: 사용자 알림 클릭 시간 - `failure_count`: 연속 발송 실패 횟수 - `last_failure_reason`: 마지막 실패 사유 ### 상태 판정 - `healthy`: 최근 24시간 안에 실제 Push 수신 기록이 있음 - `watch`: 최근 7일 안에 수신 기록은 있지만 24시간을 초과함 - `stale`: 서버 발송 성공 기록은 있으나 장기간 실제 수신 기록이 없음 - `failed`: 연속 발송 실패가 3회 이상 누적됨 - `pending`: 등록은 되어 있으나 판단할 수 있는 수신/발송 기록이 부족함 ### 자동 헬스체크 이 장치에는 systemd timer가 등록되어 있습니다. ```bash control-push-healthcheck.timer control-push-healthcheck.service ``` 실행 명령은 다음과 같습니다. ```bash /usr/bin/php /var/www/control/bin/push_healthcheck.php --min-hours=24 ``` 타이머는 활성화 후 10분 뒤 첫 실행하고, 이후 service 실행 기준 24시간마다 실행합니다. 스크립트 내부에서도 `--min-hours=24` 쿨다운을 확인하므로 중복 실행되더라도 24시간 안이면 발송을 건너뜁니다. `silent: true`는 소리와 진동을 줄이는 옵션이며 완전히 보이지 않는 알림이 아닙니다. Web Push는 사용자에게 보이는 알림을 전제로 운영합니다. ## 처리 흐름 1. 화면 진입 시 로그인 세션과 remember token을 확인합니다. 2. 대시보드는 `status` snapshot을 렌더링합니다. 3. WebSocket 연결이 성공하면 `status` 메시지로 갱신하고, 실패하면 HTTP fallback을 사용합니다. 4. 팬 조작은 상태 저장, 정책 적용, 로그 저장 순서로 처리합니다. 5. Push 등록은 권한 요청과 구독 저장이 끝나면 즉시 상태를 갱신합니다. 6. WakeLock 버튼은 활성 상태를 초록색 버튼으로 표시합니다. 7. Push 발송, 수신, 표시, 클릭 이벤트를 기록하고 구독 DB의 건강 상태를 갱신합니다. ## 주요 함수/모듈 - `collect_snapshot()`: 센서와 fan 상태 snapshot 생성 - `apply_fan_policy()`: 팬 목표값 계산과 적용 - `json_out()`: API JSON 응답 표준화 - `push_subscribe.js`: Push 구독 등록과 복구 - `push_health_summary()`: 상태별 Push 기기 수 집계 - `send_push_healthcheck_if_due()`: 쿨다운 기반 헬스체크 알림 발송 - `assets/wakelock.js`: WakeLock 버튼 상태와 Screen Wake Lock API 제어 ## 보안 - 로그인 세션과 CSRF token을 사용합니다. - POST 조작 API는 CSRF 검증을 통과해야 합니다. - sysfs 쓰기와 systemctl 실행 권한은 sudoers 범위로 제한해야 합니다. - VAPID key와 앱 비밀번호는 저장소 밖 secret 파일로 관리합니다. ## 운영 체크포인트 - 센서 수집 주기와 DB 증가량을 확인합니다. - 하드웨어 또는 OS 변경 후 fan sysfs 경로를 확인합니다. - WebSocket 장기 실행 중 DB 연결이 끊길 수 있으므로 reconnect 로그를 확인합니다. - Push 구독 자동 복구가 과도한 반복 등록을 만들지 않는지 확인합니다. - Push 헬스체크 timer 상태는 `systemctl list-timers --all control-push-healthcheck.timer`로 확인합니다. - `failed`, `stale` 기기는 알림 권한, 브라우저 데이터 삭제, PWA 재설치 여부를 확인합니다.