Control 알림과 notice 설정 세분화
This commit is contained in:
+33
-15
@@ -1720,7 +1720,7 @@ function sync_current_battery_remaining_history(array $history, array $currentRo
|
||||
}
|
||||
|
||||
$history[] = $currentRow;
|
||||
return array_slice($history, -240);
|
||||
return array_slice($history, -(int)setting_value('battery.history_sync_limit'));
|
||||
}
|
||||
|
||||
function process_service_name(int $pid): string
|
||||
@@ -1973,7 +1973,8 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
|
||||
];
|
||||
}
|
||||
|
||||
$rpmExpected = $mode !== 'off' && ($pwm >= 20 || $pwmAvg >= 20);
|
||||
$rpmExpectedPwm = (float)setting_value('notice.rpm_expected_pwm');
|
||||
$rpmExpected = $mode !== 'off' && ($pwm >= $rpmExpectedPwm || $pwmAvg >= $rpmExpectedPwm);
|
||||
|
||||
$reasons = [];
|
||||
$rpmThreshold = (float)setting_value('notice.rpm_delta_threshold');
|
||||
@@ -1984,11 +1985,12 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
|
||||
if ($rpmExpected && abs($rpmDelta) >= $rpmThreshold) $reasons[] = 'RPM ' . signed_delta_text($rpmDelta);
|
||||
if (abs($tempDelta) >= $tempThreshold) $reasons[] = 'TEMP ' . signed_delta_text($tempDelta, 'C');
|
||||
|
||||
$spiking = false;
|
||||
$alertStarted = false;
|
||||
|
||||
if ($currentState === 'normal') {
|
||||
$spiking = $reasons !== [];
|
||||
if ($spiking) {
|
||||
$alertStarted = $reasons !== [];
|
||||
if ($alertStarted) {
|
||||
$currentState = 'alert';
|
||||
save_system_notice_state(
|
||||
'alert',
|
||||
$tempAvg,
|
||||
@@ -2031,14 +2033,17 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
|
||||
}
|
||||
|
||||
$summary = 'No system notice detected in recent samples.';
|
||||
if ($spiking) {
|
||||
if ($alertStarted) {
|
||||
$summary = 'System notice: ' . implode(', ', $reasons);
|
||||
} elseif ($currentState === 'alert' && $reasons !== []) {
|
||||
$summary = 'System notice active: ' . implode(', ', $reasons);
|
||||
}
|
||||
|
||||
$alertActive = $currentState === 'alert';
|
||||
|
||||
return [
|
||||
'active' => $spiking,
|
||||
'active' => $alertActive,
|
||||
'alert_started' => $alertStarted,
|
||||
'summary' => $summary,
|
||||
'rpm_delta' => round($rpmDelta, 1),
|
||||
'pwm_delta' => round($pwmDelta, 1),
|
||||
@@ -2046,7 +2051,7 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
|
||||
'rpm_avg' => round($rpmAvg, 1),
|
||||
'pwm_avg' => round($pwmAvg, 1),
|
||||
'temp_avg' => round($tempAvg, 1),
|
||||
'notice_state' => $spiking ? 'alert' : $currentState,
|
||||
'notice_state' => $currentState,
|
||||
'baseline_source' => $currentState === 'alert' ? 'frozen_alert' : 'rolling',
|
||||
'baseline_samples' => (int)$rollingBaseline['samples'],
|
||||
];
|
||||
@@ -2148,8 +2153,9 @@ function add_fan_spike_log(array $spike, array $fan, array $system, array $proce
|
||||
$rpmDelta = round((float)($spike['rpm_delta'] ?? 0), 1);
|
||||
$pwmDelta = round((float)($spike['pwm_delta'] ?? 0), 1);
|
||||
$tempDelta = round((float)($spike['temp_delta'] ?? 0), 1);
|
||||
$spikeKey = 'fan:' . date('YmdHi');
|
||||
$loggedProcesses = notice_downward_only($tempDelta, $rpmDelta)
|
||||
$interval = max(60, (int)setting_value('notice.log_interval_seconds'));
|
||||
$spikeKey = 'fan:' . (int)floor(time() / $interval);
|
||||
$loggedProcesses = ((bool)setting_value('notice.downward_only_process_hide') && notice_downward_only($tempDelta, $rpmDelta))
|
||||
? ['cpu' => [], 'memory' => []]
|
||||
: $processes;
|
||||
|
||||
@@ -2412,7 +2418,7 @@ function send_fan_spike_notify(array $spike, array $fan, array $system, array $p
|
||||
. number_format((float)($fan['rpm'] ?? 0), 0)
|
||||
. ' RPM / PWM '
|
||||
. number_format((float)($fan['pwm'] ?? 0), 0)
|
||||
. (notice_downward_only($tempDelta, $rpmDelta) ? '' : "\n원인 후보: " . expected_process_detail_text($processes));
|
||||
. (((bool)setting_value('notice.downward_only_process_hide') && notice_downward_only($tempDelta, $rpmDelta)) ? '' : "\n원인 후보: " . expected_process_detail_text($processes));
|
||||
|
||||
return send_ha_notify([
|
||||
'title' => '시스템 유의사항',
|
||||
@@ -3224,7 +3230,7 @@ function collect_snapshot(bool $applyFan = true): array
|
||||
'throttling' => $throttledStatuses['throttling'],
|
||||
]);
|
||||
|
||||
$history = add_battery_remaining_history(sensor_history(240));
|
||||
$history = add_battery_remaining_history(sensor_history((int)setting_value('battery.history_chart_limit')));
|
||||
$batteryTrend = battery_trend_history((int)setting_value('battery.trend_hours'));
|
||||
$batteryProfile = battery_profile_history((int)setting_value('battery.profile_days'));
|
||||
$battery['remaining'] = battery_remaining_estimate($battery, $history, $batteryTrend, $batteryProfile);
|
||||
@@ -3251,23 +3257,27 @@ function collect_snapshot(bool $applyFan = true): array
|
||||
'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);
|
||||
$history = array_slice($history, -(int)setting_value('battery.history_sync_limit'));
|
||||
|
||||
$processes = process_resource_data(6);
|
||||
$fanSpike = fan_spike_analysis($history, $fan, $system, $processes);
|
||||
|
||||
if (!empty($fanSpike['active'])) {
|
||||
$shouldLogNotice = !empty($fanSpike['alert_started'])
|
||||
|| (!empty($fanSpike['active']) && (bool)setting_value('notice.log_during_alert'));
|
||||
if ($shouldLogNotice) {
|
||||
$latestNoticeNotify = latest_system_notice_notify_epoch();
|
||||
$spikeLogId = add_fan_spike_log($fanSpike, $fan, $system, $processes);
|
||||
if ($spikeLogId > 0) {
|
||||
$fanSpike['log_id'] = $spikeLogId;
|
||||
if ($latestNoticeNotify <= 0 || time() - $latestNoticeNotify >= HA_NOTIFY_SYSTEM_NOTICE_COOLDOWN) {
|
||||
$noticeCooldown = (int)setting_value('notify.system_notice_cooldown_seconds');
|
||||
if ($latestNoticeNotify <= 0 || time() - $latestNoticeNotify >= $noticeCooldown) {
|
||||
$fanSpike['notify'] = send_fan_spike_notify($fanSpike, $fan, $system, $processes);
|
||||
} else {
|
||||
$fanSpike['notify'] = [
|
||||
'sent' => 0,
|
||||
'failed' => 0,
|
||||
'skipped' => 'system_notice_cooldown',
|
||||
'cooldown_seconds' => HA_NOTIFY_SYSTEM_NOTICE_COOLDOWN,
|
||||
'cooldown_seconds' => $noticeCooldown,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -3383,6 +3393,14 @@ function control_api_dispatch(): void
|
||||
$password = (string)($_POST['password'] ?? '');
|
||||
$expectedPhrase = (string)setting_value('security.reboot_phrase');
|
||||
|
||||
if (!(bool)setting_value('security.allow_reboot')) {
|
||||
json_out([
|
||||
'ok' => false,
|
||||
'error' => 'reboot_disabled',
|
||||
'message' => '재부팅 실행이 설정에서 비활성화되어 있습니다.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
if ($phrase !== $expectedPhrase) {
|
||||
json_out([
|
||||
'ok' => false,
|
||||
|
||||
+11
-4
@@ -625,7 +625,7 @@
|
||||
return `
|
||||
<span class="settings-toggle">
|
||||
<input data-setting-key="${key}" type="checkbox" value="1" ${checked ? 'checked' : ''}>
|
||||
<span>${checked ? 'ON' : 'OFF'}</span>
|
||||
<span>${checked ? '켜기' : '끄기'}</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
@@ -662,6 +662,11 @@
|
||||
if (item.type === 'select' && item.options && item.options[item.default]) {
|
||||
return item.options[item.default];
|
||||
}
|
||||
if (item.type === 'boolean') {
|
||||
return item.default === true || item.default === 1 || item.default === '1' || item.default === 'true'
|
||||
? '켜기'
|
||||
: '끄기';
|
||||
}
|
||||
return item.default ?? '';
|
||||
};
|
||||
|
||||
@@ -687,7 +692,7 @@
|
||||
els.settingsBody.querySelectorAll('.settings-toggle input').forEach(input => {
|
||||
input.addEventListener('change', () => {
|
||||
const label = input.closest('.settings-toggle')?.querySelector('span');
|
||||
if (label) label.textContent = input.checked ? 'ON' : 'OFF';
|
||||
if (label) label.textContent = input.checked ? '켜기' : '끄기';
|
||||
});
|
||||
input.closest('.settings-toggle')?.addEventListener('click', () => {
|
||||
input.checked = !input.checked;
|
||||
@@ -1382,8 +1387,10 @@
|
||||
const m = noticeMetrics(row);
|
||||
const reasons = [];
|
||||
|
||||
if (Math.abs(m.tempDelta) >= 3) reasons.push(t(m.tempDelta >= 0 ? 'tempHigher' : 'tempLower'));
|
||||
if (Math.abs(m.rpmDelta) >= 1000) reasons.push(t(m.rpmDelta >= 0 ? 'rpmHigher' : 'rpmLower'));
|
||||
const tempThreshold = Number(settingByKey('notice.temp_delta_threshold', 3));
|
||||
const rpmThreshold = Number(settingByKey('notice.rpm_delta_threshold', 1000));
|
||||
if (Math.abs(m.tempDelta) >= tempThreshold) reasons.push(t(m.tempDelta >= 0 ? 'tempHigher' : 'tempLower'));
|
||||
if (Math.abs(m.rpmDelta) >= rpmThreshold) reasons.push(t(m.rpmDelta >= 0 ? 'rpmHigher' : 'rpmLower'));
|
||||
|
||||
return `${t('recordedReason')}: ${reasons.length ? reasons.join(', ') : t('instantChange')}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user