HA 푸시 알림 경로를 정리
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Control
|
||||
|
||||
팬 제어, 시스템 모니터링, WiFi 제어, WakeLock, Home Assistant 알림을 제공하는 PHP 기반 단일 관리 패널입니다.
|
||||
팬 제어, 시스템 모니터링, WiFi 제어, WakeLock을 제공하는 PHP 기반 단일 관리 패널입니다.
|
||||
|
||||
## 프로젝트 성격
|
||||
|
||||
@@ -26,10 +26,6 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
||||
- process CPU/MEM 후보는 프로세스 상세 접힘 영역에서 표시
|
||||
- `/etc/systemd/system/*.service` 기준 사용자 생성 서비스의 서비스명, 현재 상태, enable 상태, PID, restart 횟수, 최근 journal 로그를 진단 접힘 영역에서 표시
|
||||
- dmesg 로그는 진단 접힘 영역에서 필요할 때 열람
|
||||
- Home Assistant webhook 기반 Android 모바일 알림
|
||||
- 배터리 SOC 20% 이하 경고를 20/15/10/5% 단계로 구분하고 동일 `tag`로 갱신해 알림이 과도하게 쌓이지 않도록 처리
|
||||
- 배터리 SOC가 20%를 초과해 복구되면 같은 `tag`의 Android 알림을 `clear_notification`으로 제거
|
||||
- 최근 HA 알림 발송 성공/실패 이력은 진단 접힘 영역에 표시
|
||||
- WakeLock 버튼으로 대시보드 화면 꺼짐 방지
|
||||
- Reboot 버튼으로 2단계 확인 후 시스템 재부팅 요청
|
||||
- 기본 브라우저 alert/confirm/prompt 대신 대시보드 디자인에 맞춘 custom dialog 사용
|
||||
@@ -56,10 +52,9 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
||||
- `public/api.php`: 상태 조회와 조작 API
|
||||
- `public/assets/app.js`: 대시보드 렌더링, WebSocket, 차트, 조작 이벤트
|
||||
- `public/assets/wakelock.js`: Screen Wake Lock API 제어
|
||||
- `config/config.php`: DB, 인증, CSRF, HA 알림, shell 실행 공통 함수
|
||||
- `config/config.php`: DB, 인증, CSRF, shell 실행 공통 함수
|
||||
- `apply_policy.php`: CLI/cron 팬 정책 적용
|
||||
- `bin/control_ws.php`: WebSocket 서버. 핵심 PHP 파일 변경 감지 시 종료되고 systemd가 재시작해 새 코드를 로드
|
||||
- `bin/ha_notify_channel.php`: Android 알림 채널 제거 명령 전송용 운영 CLI
|
||||
- `bin/wifi_observe.php`: 5G WiFi 연결 시간 보정을 위한 시스템단 관측 CLI
|
||||
- `systemd/control-wifi-observe.*`: WiFi 관측 CLI를 주기적으로 실행하는 systemd unit 예시
|
||||
|
||||
@@ -74,8 +69,7 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
||||
- `wifi_observed_sessions`: 5G WiFi client의 최초/마지막 감지 시간
|
||||
- `wifi_client_aliases`: MAC별 수동 WiFi 호스트명
|
||||
- `app_settings`: 설정 모달에서 저장한 Control 동작값 오버라이드
|
||||
- `ha_notify_logs`: HA webhook 알림 발송 성공/실패 이력, 대상 서버, HTTP code, tag, 메타 정보
|
||||
- `/home/seo/secret/control.php`: 앱 비밀번호, DB 설정, 배터리 설정, HA 알림 설정
|
||||
- `/home/seo/secret/control.php`: 앱 비밀번호, DB 설정, 배터리 설정
|
||||
- 배터리 용량 설정은 `/home/seo/secret/control.php`의 `battery.cell_capacity_mah`, `battery.parallel_cells`, `battery.nominal_voltage`, `battery.capacity_wh`를 사용합니다.
|
||||
|
||||
## 배터리 잔여 시간 계산
|
||||
@@ -116,8 +110,7 @@ WebSocket 장기 실행 프로세스에서는 1분 단위 단기 집계 결과
|
||||
|
||||
- 팬 자동 제어: 팬 시작 온도, 최대 온도, 즉시 최대 PWM 온도, 자동 상승/하강 PWM step
|
||||
- 보안 정책: 자동 로그인 유지 기간, remember 쿠키 Secure/SameSite, CSRF 길이, remember 토큰 길이, User-Agent/IP 접두사 검증, 로그인 실패 잠금, 재부팅 허용 여부, 재부팅 확인 문구, 명령 timeout, WiFi 조작 허용 여부
|
||||
- 알림 정책: 배터리 긴급/위험/경고/복구 기준, 배터리 낮음/복구 알림 쿨다운, 시스템 유의사항 알림 쿨다운
|
||||
- 화면/진단 표시: 프로세스 후보 수, 사용자 서비스 로그 줄 수, 사용자 서비스 캐시 시간, 팬 이상 이력 수, HA 알림 이력 수
|
||||
- 화면/진단 표시: 프로세스 후보 수, 사용자 서비스 로그 줄 수, 사용자 서비스 캐시 시간, 팬 이상 이력 수
|
||||
- 저전압/스로틀링: 최근 판정창, 복구 중 유지 시간, 반복 발생 기준 횟수
|
||||
- 팬 이상감지: 기준 표본 수, 최신 표본 제외 수, RPM/온도 이상 감지 차이, RPM/온도 복구 차이, RPM 감시 시작 PWM, alert 유지 중 반복 기록, 반복 기록 간격, 하강 변화 원인 후보 표시 여부
|
||||
- 배터리 예측: 단기/장기 학습 범위, 후보 필터 비율, 부하 보정 강도, 전압 하한, 용량 모델 가중치, 잔여시간 현실 상한, 최소 시스템 전력, 상한 초과 후보 감쇠, 에너지/전압 모델 사용 여부, 상태/잔여시간 차트 표본 수
|
||||
@@ -136,38 +129,20 @@ WebSocket 장기 실행 프로세스에서는 1분 단위 단기 집계 결과
|
||||
- WebSocket 소스 변경 감지: 15초마다 확인 후 재시작
|
||||
- 팬 슬라이더 자동 적용 debounce: 약 450ms
|
||||
|
||||
## HA 알림 구조
|
||||
## System Notice 구조
|
||||
|
||||
Control은 서버에서 Home Assistant webhook으로 알림 payload를 보내고, HA 자동화가 `notify.mobile_app_seocaegeonyi_z_fold7` 서비스로 Android 알림을 전달합니다.
|
||||
|
||||
- webhook id: `/home/seo/secret/control.php`의 `ha_notify.webhook_id`
|
||||
- 기본 발송 순서: 서울 HA `https://ha.seoul.chaegeon.com` 우선, 실패 시 목포 HA `https://ha.chaegeon.com`
|
||||
- payload 형식: `title`, `message`, `data`
|
||||
- Android 알림 속성은 `data`에 넣어 HA mobile app으로 전달
|
||||
- 사용 속성: `tag`, `group`, `channel`, `importance`, `priority`, `ttl`, `sticky`, `persistent`, `renotify`, `color`, `notification_icon`, `vibrationPattern`, `ledColor`, `visibility`, `timeout`, `clickAction`, `url`, `actions`
|
||||
- 발송 결과는 `ha_notify_logs`에 저장
|
||||
|
||||
배터리 SOC 낮음 경고는 `control-battery-low` tag를 사용합니다. SOC 값이 조금씩 달라져도 Android 알림은 같은 tag로 갱신되어 알림 목록에 여러 장이 계속 쌓이지 않습니다. 주의/경고/위험/긴급/복구 기준과 알림 쿨다운은 설정 모달의 알림 정책에서 조정합니다.
|
||||
|
||||
System Notice는 `control-system-notice` tag를 사용하며, 설정된 쿨다운으로 급격한 팬/온도 변화 알림을 제한합니다. alert 상태는 신규 진입과 유지 상태를 분리해 관리하며, alert 유지 중 반복 기록 여부와 기록 간격도 설정 모달에서 조정합니다.
|
||||
Control은 급격한 팬/온도 변화를 외부 푸시로 보내지 않고 `system_notice_logs`에 로컬 이력으로 저장합니다. 대시보드는 최근 이력을 진단 영역에서 보여주며, 배터리 SOC 낮음 같은 모바일 푸시 발송은 더 이상 수행하지 않습니다.
|
||||
|
||||
### 시스템 알림 조건
|
||||
|
||||
배터리 알림과 System Notice는 서로 다른 조건으로 동작합니다.
|
||||
System Notice는 다음 조건으로 동작합니다.
|
||||
|
||||
- 배터리 알림: 현재 배터리 SOC가 설정값 이하로 내려가면 발송합니다. 기본 단계는 20% 이하 주의, 15% 이하 경고, 10% 이하 위험, 5% 이하 긴급입니다. 같은 `control-battery-low` tag를 계속 갱신하므로 SOC 값이 1%씩 바뀌어도 알림 카드가 계속 쌓이지 않습니다. SOC가 복구 기준을 넘으면 같은 tag를 `clear_notification`으로 제거합니다.
|
||||
- System Notice 시작: 팬 모드가 `off`가 아닐 때, 최근 안정 기준선 대비 팬 RPM 차이가 `팬 RPM 이상 감지 차이` 이상이거나 온도 차이가 `온도 이상 감지 차이` 이상이면 alert로 진입합니다. RPM 감시는 현재 PWM 또는 기준 PWM이 `RPM 감시 시작 PWM` 이상일 때만 의미 있는 변화로 봅니다.
|
||||
- System Notice 기준선: normal 상태에서는 최근 sensor history에서 최신 몇 개 표본을 제외하고 절사 평균으로 기준선을 계속 갱신합니다. alert로 들어가면 진입 당시 온도/RPM/PWM 기준선을 고정해, alert 중 기준선이 문제 상태를 따라가며 사라지는 일을 막습니다.
|
||||
- System Notice 복구: 고정 기준선 또는 최신 rolling 기준선 대비 RPM/온도 차이가 각각 복구 차이 이하로 내려가면 normal로 돌아갑니다. 팬 모드가 `off`이면 fan off 기준선을 별도로 고정하고 System Notice alert를 만들지 않습니다.
|
||||
- System Notice 기록/발송: alert 신규 진입 시 `system_notice_logs`에 기록합니다. `Alert 유지 중 반복 기록`을 켜면 유지 중에도 설정한 반복 기록 간격마다 다시 기록할 수 있습니다. HA 알림은 `시스템 유의사항 알림 쿨다운`을 통과할 때만 발송합니다.
|
||||
- System Notice 기록: alert 신규 진입 시 `system_notice_logs`에 기록합니다. `Alert 유지 중 반복 기록`을 켜면 유지 중에도 설정한 반복 기록 간격마다 다시 기록할 수 있습니다.
|
||||
- 저전압/스로틀링 표시: `vcgencmd get_throttled`의 현재 비트와 부팅 후 이력 비트를 읽어 현재 상태, 최근 감지, 지속시간, 최근 10분 통계를 표시합니다. 이 값은 System Notice와 별개이며, 팬/온도 alert 조건에는 직접 섞지 않습니다.
|
||||
|
||||
Android 알림 채널은 생성 후 휴대폰 설정에 의해 중요도와 진동 패턴이 고정될 수 있습니다. 채널을 다시 만들 필요가 있을 때는 운영 CLI로 제거 명령을 보낸 뒤 다음 알림에서 재생성합니다.
|
||||
|
||||
```bash
|
||||
/usr/bin/php /var/www/control/bin/ha_notify_channel.php --remove=control_battery
|
||||
```
|
||||
|
||||
## WiFi 관측 자동화
|
||||
|
||||
5G 외부 WiFi 모듈은 `iw station dump`에 `connected time`을 제공하지 않는 경우가 있어, 서버가 MAC별 최초 감지 시각을 DB에 저장하고 경과 시간을 계산합니다.
|
||||
@@ -185,7 +160,7 @@ control-wifi-observe.service
|
||||
/usr/bin/php /var/www/control/bin/wifi_observe.php
|
||||
```
|
||||
|
||||
이 작업은 팬 정책, 차트 로그 저장, HA 알림 발송과 분리되어 있으며 WiFi client 목록 확인과 `wifi_observed_sessions` 갱신만 수행합니다.
|
||||
이 작업은 팬 정책, 차트 로그 저장, System Notice 기록과 분리되어 있으며 WiFi client 목록 확인과 `wifi_observed_sessions` 갱신만 수행합니다.
|
||||
|
||||
호스트명은 dnsmasq lease 값을 우선 사용합니다. lease hostname이 `N/A`이면 MAC 주소 끝 6자리 기반 임시명 `기기-XXXXXX`을 표시하고, 표의 호스트명을 클릭해 저장한 수동 이름은 `wifi_client_aliases`에 보관해 이후에도 우선 표시합니다.
|
||||
|
||||
@@ -207,9 +182,8 @@ control-wifi-observe.service
|
||||
12. 저전압/스로틀링 상태 파일에는 최근 episode 시작/종료를 보관하고, 최근 10분 발생 횟수, 감지 누적시간, 감지 비율을 계산합니다.
|
||||
13. 배터리 잔여 시간은 최근 24시간 SOC 방전 추세와 최대 45일 장기 학습 프로파일을 함께 평가하고, 현재 CPU 전력 변화와 현실 상한을 반영합니다.
|
||||
14. 잔여 시간 차트의 마지막 지점은 현재 snapshot의 잔여 시간과 같은 값을 사용하도록 history 응답을 동기화합니다.
|
||||
15. 배터리 SOC 또는 System Notice 조건이 맞으면 Control이 HA webhook으로 알림을 발송하고 `ha_notify_logs`에 결과를 저장합니다.
|
||||
16. 대시보드는 최근 HA 알림 성공/실패 이력을 `ha_notify_logs`에서 읽어 진단 접힘 영역에 표시합니다.
|
||||
17. 대시보드 첫 화면에는 팬/전원/스로틀링/WiFi/핵심 차트를 우선 배치하고, 상세 차트, 프로세스 후보, 사용자 서비스, HA 알림 이력, dmesg는 접힘 영역으로 분리합니다.
|
||||
15. System Notice 조건이 맞으면 Control이 `system_notice_logs`에 이력을 저장합니다.
|
||||
16. 대시보드 첫 화면에는 팬/전원/스로틀링/WiFi/핵심 차트를 우선 배치하고, 상세 차트, 프로세스 후보, 사용자 서비스, dmesg는 접힘 영역으로 분리합니다.
|
||||
|
||||
## 주요 함수/모듈
|
||||
|
||||
@@ -224,12 +198,6 @@ control-wifi-observe.service
|
||||
- `apply_observed_wifi_connected_time()`: 5G WiFi 연결 시간이 없는 client에 서버 관측 경과 시간 적용
|
||||
- `wifi_client_aliases()`, `save_wifi_client_alias()`: MAC별 WiFi 호스트명 조회와 저장
|
||||
- `apply_wifi_estimates()`: WiFi 신호/송신 속도/수신 속도 결측값 보정
|
||||
- `send_ha_notify()`: HA webhook 알림 발송, 서울 우선/목포 fallback, 성공/실패 로그 저장
|
||||
- `ha_notify_due()`: 동일 tag 기준 쿨다운 판정
|
||||
- `clear_ha_notification()`: 같은 tag의 Android 알림 제거 명령 발송
|
||||
- `battery_low_notify_profile()`: 배터리 SOC 단계별 채널, 중요도, 아이콘, 진동 정책 선택
|
||||
- `send_battery_low_notify_if_needed()`: 설정된 배터리 SOC 기준에 따라 낮음/복구 알림 발송
|
||||
- `ha_notify_log_rows()`: 대시보드 HA 알림 이력 조회
|
||||
- `battery_trend_history()`: 최근 24시간 배터리 기록을 1분 단위로 집계
|
||||
- `battery_profile_history()`: 최대 45일 배터리 기록을 약 5분 간격으로 샘플링하고 파일 캐시로 보관
|
||||
- `weighted_linear_regression()`, `numeric_mad()`: SOC 기울기 계산과 회귀 잔차 튐 제거
|
||||
@@ -245,7 +213,6 @@ control-wifi-observe.service
|
||||
- `sync_current_battery_remaining_history()`: 잔여 시간 차트 마지막 지점을 현재 snapshot 잔여 시간과 동기화
|
||||
- `batteryRemainingTitle()`, `showBatteryTooltip()`, `updateBatteryTooltip()`: 잔여 시간 계산 근거 커스텀 팝오버 표시와 실시간 갱신
|
||||
- `setting_definitions()`, `settings_payload()`, `save_settings()`, `reset_settings()`: 설정 모달 항목 정의, 조회, 저장, 초기화
|
||||
- `bin/ha_notify_channel.php`: Android 알림 채널 제거 명령 CLI
|
||||
- `bin/wifi_observe.php`: 화면 접속 없이 `wifi_data()`를 호출해 5G 관측 세션을 선제 갱신
|
||||
- `assets/wakelock.js`: WakeLock 버튼 상태와 Screen Wake Lock API 제어
|
||||
- `customAlert()`, `customConfirm()`, `customPrompt()`: 대시보드 공통 확인/입력 dialog
|
||||
@@ -261,8 +228,7 @@ control-wifi-observe.service
|
||||
- 로그인 화면은 CSRF 검사를 수행하고, 설정한 실패 횟수/집계 시간/잠금 시간에 따라 세션 단위 잠금을 적용합니다.
|
||||
- Remember login은 설정에 따라 Secure/SameSite, 토큰 길이, 만료 기간, User-Agent 고정, IPv4 접두사 고정을 조정할 수 있습니다.
|
||||
- WiFi restart/reload 허용 여부와 root 명령 timeout은 설정 모달에서 조정합니다.
|
||||
- 앱 비밀번호와 HA 알림 설정은 저장소 밖 secret 파일로 관리합니다.
|
||||
- HA webhook id는 `/home/seo/secret/control.php`의 `ha_notify.webhook_id`에 둡니다. 값이 없으면 발송하지 않고 `ha_notify_logs`에 실패로 기록합니다.
|
||||
- 앱 비밀번호와 DB/배터리 설정은 저장소 밖 secret 파일로 관리합니다.
|
||||
|
||||
## 운영 체크포인트
|
||||
|
||||
@@ -276,9 +242,7 @@ control-wifi-observe.service
|
||||
- `control-wifi-observe.timer`는 10초마다 `/var/www/control/bin/wifi_observe.php`를 실행해 사용자가 대시보드에 접속하지 않아도 5G 연결 시간 카운터를 시작하고 유지합니다.
|
||||
- WebSocket은 장기 실행 프로세스이므로 `public/api.php`, `config/config.php`, `bin/control_ws.php` 변경을 감지하면 15초 안에 종료되고 `control-websocket.service`가 새 프로세스로 재시작합니다.
|
||||
- WebSocket 장기 실행 중 DB 연결이 끊길 수 있으므로 reconnect 로그를 확인합니다.
|
||||
- HA 알림 자동화는 서울 `/home/seo/homeassistant/automations.yaml`, 목포 `/mnt/synology-docker/homeassistant/config/automations.yaml` 양쪽의 `CONTROL_HA_NOTIFY_WEBHOOK` 계열 항목에서 관리합니다.
|
||||
- SmartThings 재로드 자동화는 서울 전력분전반과 목포 누전차단기 전력 센서의 값이 10초 이상 변하지 않으면 통합을 재로드합니다.
|
||||
- HA 알림 채널의 중요도나 진동이 예상과 다르면 휴대폰 알림 채널 설정을 확인하거나 `bin/ha_notify_channel.php`로 해당 채널 제거 명령을 보냅니다.
|
||||
- Reboot API 사용 전 웹 서버 실행 계정의 sudoers에 `/usr/sbin/reboot` 비밀번호 없는 실행 권한이 제한적으로 설정되어 있는지 확인합니다.
|
||||
- 저전압/스로틀링이 `N/A`로 보이면 웹 서버 실행 계정의 `/dev/vcio` 접근 권한과 `/usr/bin/vcgencmd get_throttled` sudoers 허용 여부를 확인합니다.
|
||||
- 언어/테마 표시가 예상과 다르면 브라우저 localStorage의 `controlLang`, `controlTheme` 값을 확인합니다.
|
||||
|
||||
Reference in New Issue
Block a user