잔여 시간 차트 최신값 동기화

This commit is contained in:
seo
2026-06-26 02:41:54 +09:00
parent 68079e7ff4
commit b0714f9ff2
2 changed files with 50 additions and 3 deletions
+7 -3
View File
@@ -92,6 +92,8 @@ WebSocket 장기 실행 프로세스에서는 1분 단위 단기 집계 결과
팝오버는 계산 잔여 시간, 시간당 SOC 감소율, 추세 신뢰도, 최근 CPU 전력, 계산 출처, 반영 구간을 표시합니다. 각 후보별로 최근 30분/1시간/3시간/6시간/12시간/24시간 감소율, 신뢰도, 부하 보정 배율을 표시하고, 장기 학습 후보는 반영된 학습 구간 수와 SOC 구간 수를 함께 표시합니다.
잔여 시간 차트의 마지막 지점은 현재 snapshot의 `battery.remaining.seconds`와 동기화합니다. DB에 저장된 마지막 센서 기록이 몇 초 늦어도 좌측 상태 영역과 차트의 최신 잔여 시간이 서로 다른 값을 보여주지 않도록, API 응답 history 끝에 현재 snapshot row를 반영합니다.
## 갱신 주기
- WebSocket 상태 갱신: 1초마다
@@ -163,9 +165,10 @@ control-wifi-observe.service
11. 시스템 상태는 `vcgencmd get_throttled`를 읽어 현재 저전압/스로틀링 여부와 부팅 후 이력, 최근 감지 시각, 현재/최근 지속시간을 표시합니다.
12. 저전압/스로틀링 상태 파일에는 최근 episode 시작/종료를 보관하고, 최근 10분 발생 횟수, 감지 누적시간, 감지 비율을 계산합니다.
13. 배터리 잔여 시간은 최근 24시간 SOC 방전 추세와 최대 45일 장기 학습 프로파일을 함께 평가하고, 현재 CPU 전력 변화로 보정합니다.
14. 배터리 SOC 또는 System Notice 조건이 맞으면 Control이 HA webhook으로 알림을 발송하고 `ha_notify_logs`에 결과를 저장합니다.
15. 대시보드는 최근 HA 알림 성공/실패 이력을 `ha_notify_logs`서 읽어 진단 접힘 영역에 표시합니다.
16. 대시보드 첫 화면에는 팬/전원/스로틀링/WiFi/핵심 차트를 우선 배치하고, 상세 차트, 프로세스 후보, 사용자 서비스, HA 알림 이력, dmesg는 접힘 영역으로 분리합니다.
14. 잔여 시간 차트의 마지막 지점은 현재 snapshot의 잔여 시간과 같은 값을 사용하도록 history 응답을 동기화합니다.
15. 배터리 SOC 또는 System Notice 조건이 맞으면 Control이 HA webhook으로 알림을 발송하고 `ha_notify_logs` 결과를 저장합니다.
16. 대시보드는 최근 HA 알림 성공/실패 이력을 `ha_notify_logs`에서 읽어 진단 접힘 영역에 표시합니다.
17. 대시보드 첫 화면에는 팬/전원/스로틀링/WiFi/핵심 차트를 우선 배치하고, 상세 차트, 프로세스 후보, 사용자 서비스, HA 알림 이력, dmesg는 접힘 영역으로 분리합니다.
## 주요 함수/모듈
@@ -191,6 +194,7 @@ control-wifi-observe.service
- `battery_learned_profile_candidate()`: 누적 기록에서 SOC/부하 구간별 장기 방전 프로파일 후보 계산
- `battery_remaining_estimate()`: SOC 다중 시간창 방전 추세, 장기 학습 프로파일, 현재 부하 보정으로 잔여 시간 계산
- `battery_power_fallback_estimate()`: SOC 추세가 부족할 때 배터리 용량과 최근 CPU 전력 평균으로 잔여 시간 대체 계산
- `sync_current_battery_remaining_history()`: 잔여 시간 차트 마지막 지점을 현재 snapshot 잔여 시간과 동기화
- `batteryRemainingTitle()`, `showBatteryTooltip()`, `updateBatteryTooltip()`: 잔여 시간 계산 근거 커스텀 팝오버 표시와 실시간 갱신
- `bin/ha_notify_channel.php`: Android 알림 채널 제거 명령 CLI
- `bin/wifi_observe.php`: 화면 접속 없이 `wifi_data()`를 호출해 5G 관측 세션을 선제 갱신
+43
View File
@@ -1211,6 +1211,26 @@ function add_battery_remaining_history(array $history): array
return $history;
}
function sync_current_battery_remaining_history(array $history, array $currentRow, mixed $remainingSeconds): array
{
$currentRow['battery_remaining_seconds'] = is_numeric($remainingSeconds)
? (int)round((float)$remainingSeconds)
: null;
$now = strtotime((string)($currentRow['time'] ?? ''));
$lastIndex = count($history) - 1;
if ($lastIndex >= 0) {
$lastTime = strtotime((string)($history[$lastIndex]['time'] ?? ''));
if ($now > 0 && $lastTime > 0 && abs($now - $lastTime) <= 5) {
$history[$lastIndex] = array_merge($history[$lastIndex], $currentRow);
return $history;
}
}
$history[] = $currentRow;
return array_slice($history, -240);
}
function process_service_name(int $pid): string
{
$cgroup = @file('/proc/' . $pid . '/cgroup', FILE_IGNORE_NEW_LINES) ?: [];
@@ -2709,6 +2729,29 @@ function collect_snapshot(bool $applyFan = true): array
$batteryTrend = battery_trend_history(24);
$batteryProfile = battery_profile_history(45);
$battery['remaining'] = battery_remaining_estimate($battery, $history, $batteryTrend, $batteryProfile);
$history = sync_current_battery_remaining_history($history, [
'time' => date('Y-m-d H:i:s'),
'temp_c' => $temp,
'fan_rpm' => $rpm,
'fan_efficiency' => fan_efficiency($rpm, $temp, $cpuPower['watts'] ?? null),
'rp1_temp_c' => rp1_temp_c(),
'cpu_voltage' => $cpuPower['voltage'],
'cpu_watts' => $cpuPower['watts'],
'battery_voltage' => $battery['voltage'],
'battery_percent' => $battery['percent'],
'fan_pwm' => $pwm,
'pwm_percent' => round($pwm / 255 * 100, 2),
'pwm_mode' => $policy['mode'],
'cpu_load_1' => round((float)$load[0], 2),
'cpu_load_5' => round((float)$load[1], 2),
'cpu_load_15' => round((float)$load[2], 2),
'disk_total_kb' => $disk['total_kb'],
'disk_used_kb' => $disk['used_kb'],
'disk_free_kb' => $disk['free_kb'],
'mem_total_mb' => $mem['total_mb'],
'mem_used_mb' => $mem['used_mb'],
'mem_percent' => $mem['total_mb'] > 0 ? round($mem['used_mb'] / $mem['total_mb'] * 100, 1) : 0,
], $battery['remaining']['seconds'] ?? null);
$processes = process_resource_data(6);
$fanSpike = fan_spike_analysis($history, $fan, $system, $processes);