네트워크 오류 드롭 이력 추가
This commit is contained in:
@@ -16,7 +16,7 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
|||||||
- 오버레이 설정 모달에서 보안 정책, 팬 자동곡선, 이벤트 판정, 팬 이상감지 파라미터 조정
|
- 오버레이 설정 모달에서 보안 정책, 팬 자동곡선, 이벤트 판정, 팬 이상감지 파라미터 조정
|
||||||
- 설정 모달에서 라즈베리파이 정품 7인치 DSI 터치 디스플레이 상태 확인, 밝기/백라이트 즉시 적용, 콘솔 회전, 터치 좌표 보정, LCD/터치 비활성화 부팅 설정 조정
|
- 설정 모달에서 라즈베리파이 정품 7인치 DSI 터치 디스플레이 상태 확인, 밝기/백라이트 즉시 적용, 콘솔 회전, 터치 좌표 보정, LCD/터치 비활성화 부팅 설정 조정
|
||||||
- CPU 온도, RP1 온도, CPU 전력, 팬 RPM 센서 이력 차트
|
- CPU 온도, RP1 온도, CPU 전력, 팬 RPM 센서 이력 차트
|
||||||
- DHCP client 목록 아래에서 WAN, LAN, 2.4G WiFi, 5G WiFi 기준 다운로드/업로드 속도와 RX/TX 패킷 이력 차트 표시
|
- DHCP client 목록 아래에서 WAN, LAN, 2.4G WiFi, 5G WiFi 기준 다운로드/업로드 속도, RX/TX 패킷, 오류/드롭 이력 차트 표시
|
||||||
- UPS/배터리 잔여 시간 기능은 장치 제거 후 비활성 상태로 두고, 배터리 센서 조회와 장기 학습 계산은 돌리지 않음
|
- UPS/배터리 잔여 시간 기능은 장치 제거 후 비활성 상태로 두고, 배터리 센서 조회와 장기 학습 계산은 돌리지 않음
|
||||||
- 라즈베리파이 저전압/스로틀링 현재 상태, 복구 중/반복 발생 판정, 부팅 후 이력, 최근 감지 시각, 지속시간, 최근 10분 통계 표시
|
- 라즈베리파이 저전압/스로틀링 현재 상태, 복구 중/반복 발생 판정, 부팅 후 이력, 최근 감지 시각, 지속시간, 최근 10분 통계 표시
|
||||||
- WiFi/LAN client 목록과 2.4G/5G/LAN client 수 표시
|
- WiFi/LAN client 목록과 2.4G/5G/LAN client 수 표시
|
||||||
@@ -76,7 +76,7 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
|||||||
- `control_state`: 팬 모드와 PWM 상태
|
- `control_state`: 팬 모드와 PWM 상태
|
||||||
- `presence_fan_policy_state`: 외출/귀가 기반 팬 정책의 마지막 확인/적용 상태
|
- `presence_fan_policy_state`: 외출/귀가 기반 팬 정책의 마지막 확인/적용 상태
|
||||||
- `sensor_logs`: 온도, RPM, PWM, load, memory, disk, uptime. 과거 배터리 컬럼은 호환을 위해 유지하지만 UPS 제거 상태에서는 새 배터리값을 기록하지 않습니다.
|
- `sensor_logs`: 온도, RPM, PWM, load, memory, disk, uptime. 과거 배터리 컬럼은 호환을 위해 유지하지만 UPS 제거 상태에서는 새 배터리값을 기록하지 않습니다.
|
||||||
- `network_usage_logs`: WAN, LAN, 2.4G WiFi, 5G WiFi 기준 누적 byte/packet 카운터와 초당 다운로드/업로드 속도, RX/TX 패킷 이력
|
- `network_usage_logs`: WAN, LAN, 2.4G WiFi, 5G WiFi 기준 누적 byte/packet/error/drop 카운터와 초당 다운로드/업로드 속도, RX/TX 패킷, 오류/드롭 이력
|
||||||
- `power_event_states`: 저전압/스로틀링 episode 상태, 최근 지속시간, 최근 이벤트 이력
|
- `power_event_states`: 저전압/스로틀링 episode 상태, 최근 지속시간, 최근 이벤트 이력
|
||||||
- `battery_profile_cache`: 배터리 잔여시간 계산용 장기 프로파일 캐시
|
- `battery_profile_cache`: 배터리 잔여시간 계산용 장기 프로파일 캐시
|
||||||
- `systemd_service_cache`: 사용자 생성 systemd 서비스 목록과 최근 journal 로그의 짧은 TTL 캐시
|
- `systemd_service_cache`: 사용자 생성 systemd 서비스 목록과 최근 journal 로그의 짧은 TTL 캐시
|
||||||
|
|||||||
@@ -599,11 +599,19 @@ function bootstrap_db(): void
|
|||||||
tx_bytes BIGINT UNSIGNED NOT NULL,
|
tx_bytes BIGINT UNSIGNED NOT NULL,
|
||||||
rx_packets BIGINT UNSIGNED NOT NULL,
|
rx_packets BIGINT UNSIGNED NOT NULL,
|
||||||
tx_packets BIGINT UNSIGNED NOT NULL,
|
tx_packets BIGINT UNSIGNED NOT NULL,
|
||||||
|
rx_errors BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
tx_errors BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
rx_dropped BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
tx_dropped BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
rx_mbps DECIMAL(12,4) NULL,
|
rx_mbps DECIMAL(12,4) NULL,
|
||||||
tx_mbps DECIMAL(12,4) NULL,
|
tx_mbps DECIMAL(12,4) NULL,
|
||||||
rx_pps DECIMAL(12,2) NULL,
|
rx_pps DECIMAL(12,2) NULL,
|
||||||
tx_pps DECIMAL(12,2) NULL,
|
tx_pps DECIMAL(12,2) NULL,
|
||||||
|
rx_errors_per_sec DECIMAL(12,2) NULL,
|
||||||
|
tx_errors_per_sec DECIMAL(12,2) NULL,
|
||||||
|
rx_dropped_per_sec DECIMAL(12,2) NULL,
|
||||||
|
tx_dropped_per_sec DECIMAL(12,2) NULL,
|
||||||
|
|
||||||
create_ip VARCHAR(64) NULL,
|
create_ip VARCHAR(64) NULL,
|
||||||
|
|
||||||
@@ -688,6 +696,14 @@ function bootstrap_db(): void
|
|||||||
"ALTER TABLE system_notice_state ADD COLUMN active_temp_delta DECIMAL(8,2) NULL AFTER active_reason",
|
"ALTER TABLE system_notice_state ADD COLUMN active_temp_delta DECIMAL(8,2) NULL AFTER active_reason",
|
||||||
"ALTER TABLE system_notice_state ADD COLUMN active_rpm_delta DECIMAL(12,2) NULL AFTER active_temp_delta",
|
"ALTER TABLE system_notice_state ADD COLUMN active_rpm_delta DECIMAL(12,2) NULL AFTER active_temp_delta",
|
||||||
"ALTER TABLE system_notice_state ADD COLUMN process_signature VARCHAR(255) NULL AFTER active_rpm_delta",
|
"ALTER TABLE system_notice_state ADD COLUMN process_signature VARCHAR(255) NULL AFTER active_rpm_delta",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN rx_errors BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER tx_packets",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN tx_errors BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER rx_errors",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN rx_dropped BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER tx_errors",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN tx_dropped BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER rx_dropped",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN rx_errors_per_sec DECIMAL(12,2) NULL AFTER tx_pps",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN tx_errors_per_sec DECIMAL(12,2) NULL AFTER rx_errors_per_sec",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN rx_dropped_per_sec DECIMAL(12,2) NULL AFTER tx_errors_per_sec",
|
||||||
|
"ALTER TABLE network_usage_logs ADD COLUMN tx_dropped_per_sec DECIMAL(12,2) NULL AFTER rx_dropped_per_sec",
|
||||||
"ALTER TABLE sensor_logs DROP COLUMN disk_total_gb",
|
"ALTER TABLE sensor_logs DROP COLUMN disk_total_gb",
|
||||||
"ALTER TABLE sensor_logs DROP COLUMN disk_used_gb",
|
"ALTER TABLE sensor_logs DROP COLUMN disk_used_gb",
|
||||||
"ALTER TABLE sensor_logs DROP COLUMN disk_free_gb",
|
"ALTER TABLE sensor_logs DROP COLUMN disk_free_gb",
|
||||||
|
|||||||
+51
-1
@@ -1048,6 +1048,10 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
$txBytes = isset($iface['tx_bytes']) ? (int)$iface['tx_bytes'] : -1;
|
$txBytes = isset($iface['tx_bytes']) ? (int)$iface['tx_bytes'] : -1;
|
||||||
$rxPackets = isset($iface['rx_packets']) ? (int)$iface['rx_packets'] : -1;
|
$rxPackets = isset($iface['rx_packets']) ? (int)$iface['rx_packets'] : -1;
|
||||||
$txPackets = isset($iface['tx_packets']) ? (int)$iface['tx_packets'] : -1;
|
$txPackets = isset($iface['tx_packets']) ? (int)$iface['tx_packets'] : -1;
|
||||||
|
$rxErrors = isset($iface['rx_errors']) ? (int)$iface['rx_errors'] : 0;
|
||||||
|
$txErrors = isset($iface['tx_errors']) ? (int)$iface['tx_errors'] : 0;
|
||||||
|
$rxDropped = isset($iface['rx_dropped']) ? (int)$iface['rx_dropped'] : 0;
|
||||||
|
$txDropped = isset($iface['tx_dropped']) ? (int)$iface['tx_dropped'] : 0;
|
||||||
if ($name === '' || $rxBytes < 0 || $txBytes < 0 || $rxPackets < 0 || $txPackets < 0) {
|
if ($name === '' || $rxBytes < 0 || $txBytes < 0 || $rxPackets < 0 || $txPackets < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1060,6 +1064,10 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
tx_bytes,
|
tx_bytes,
|
||||||
rx_packets,
|
rx_packets,
|
||||||
tx_packets,
|
tx_packets,
|
||||||
|
rx_errors,
|
||||||
|
tx_errors,
|
||||||
|
rx_dropped,
|
||||||
|
tx_dropped,
|
||||||
TIMESTAMPDIFF(MICROSECOND, recorded_at, NOW(3)) AS elapsed_us
|
TIMESTAMPDIFF(MICROSECOND, recorded_at, NOW(3)) AS elapsed_us
|
||||||
FROM network_usage_logs
|
FROM network_usage_logs
|
||||||
WHERE iface = :iface
|
WHERE iface = :iface
|
||||||
@@ -1073,6 +1081,10 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
$txMbps = null;
|
$txMbps = null;
|
||||||
$rxPps = null;
|
$rxPps = null;
|
||||||
$txPps = null;
|
$txPps = null;
|
||||||
|
$rxErrorsPerSec = null;
|
||||||
|
$txErrorsPerSec = null;
|
||||||
|
$rxDroppedPerSec = null;
|
||||||
|
$txDroppedPerSec = null;
|
||||||
if ($previous) {
|
if ($previous) {
|
||||||
$seconds = max(0.0, (float)($previous['elapsed_us'] ?? 0) / 1000000);
|
$seconds = max(0.0, (float)($previous['elapsed_us'] ?? 0) / 1000000);
|
||||||
if ($seconds < 0.8) {
|
if ($seconds < 0.8) {
|
||||||
@@ -1083,12 +1095,22 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
$txDelta = $txBytes - (int)$previous['tx_bytes'];
|
$txDelta = $txBytes - (int)$previous['tx_bytes'];
|
||||||
$rxPacketDelta = $rxPackets - (int)$previous['rx_packets'];
|
$rxPacketDelta = $rxPackets - (int)$previous['rx_packets'];
|
||||||
$txPacketDelta = $txPackets - (int)$previous['tx_packets'];
|
$txPacketDelta = $txPackets - (int)$previous['tx_packets'];
|
||||||
|
$rxErrorDelta = $rxErrors - (int)$previous['rx_errors'];
|
||||||
|
$txErrorDelta = $txErrors - (int)$previous['tx_errors'];
|
||||||
|
$rxDroppedDelta = $rxDropped - (int)$previous['rx_dropped'];
|
||||||
|
$txDroppedDelta = $txDropped - (int)$previous['tx_dropped'];
|
||||||
if ($seconds > 0 && $seconds <= 60 && $rxDelta >= 0 && $txDelta >= 0 && $rxPacketDelta >= 0 && $txPacketDelta >= 0) {
|
if ($seconds > 0 && $seconds <= 60 && $rxDelta >= 0 && $txDelta >= 0 && $rxPacketDelta >= 0 && $txPacketDelta >= 0) {
|
||||||
$rxMbps = round(($rxDelta * 8) / $seconds / 1000000, 4);
|
$rxMbps = round(($rxDelta * 8) / $seconds / 1000000, 4);
|
||||||
$txMbps = round(($txDelta * 8) / $seconds / 1000000, 4);
|
$txMbps = round(($txDelta * 8) / $seconds / 1000000, 4);
|
||||||
$rxPps = round($rxPacketDelta / $seconds, 2);
|
$rxPps = round($rxPacketDelta / $seconds, 2);
|
||||||
$txPps = round($txPacketDelta / $seconds, 2);
|
$txPps = round($txPacketDelta / $seconds, 2);
|
||||||
}
|
}
|
||||||
|
if ($seconds > 0 && $seconds <= 60 && $rxErrorDelta >= 0 && $txErrorDelta >= 0 && $rxDroppedDelta >= 0 && $txDroppedDelta >= 0) {
|
||||||
|
$rxErrorsPerSec = round($rxErrorDelta / $seconds, 2);
|
||||||
|
$txErrorsPerSec = round($txErrorDelta / $seconds, 2);
|
||||||
|
$rxDroppedPerSec = round($rxDroppedDelta / $seconds, 2);
|
||||||
|
$txDroppedPerSec = round($txDroppedDelta / $seconds, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
@@ -1099,10 +1121,18 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
tx_bytes,
|
tx_bytes,
|
||||||
rx_packets,
|
rx_packets,
|
||||||
tx_packets,
|
tx_packets,
|
||||||
|
rx_errors,
|
||||||
|
tx_errors,
|
||||||
|
rx_dropped,
|
||||||
|
tx_dropped,
|
||||||
rx_mbps,
|
rx_mbps,
|
||||||
tx_mbps,
|
tx_mbps,
|
||||||
rx_pps,
|
rx_pps,
|
||||||
tx_pps,
|
tx_pps,
|
||||||
|
rx_errors_per_sec,
|
||||||
|
tx_errors_per_sec,
|
||||||
|
rx_dropped_per_sec,
|
||||||
|
tx_dropped_per_sec,
|
||||||
create_ip
|
create_ip
|
||||||
)
|
)
|
||||||
VALUES
|
VALUES
|
||||||
@@ -1112,10 +1142,18 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
:tx_bytes,
|
:tx_bytes,
|
||||||
:rx_packets,
|
:rx_packets,
|
||||||
:tx_packets,
|
:tx_packets,
|
||||||
|
:rx_errors,
|
||||||
|
:tx_errors,
|
||||||
|
:rx_dropped,
|
||||||
|
:tx_dropped,
|
||||||
:rx_mbps,
|
:rx_mbps,
|
||||||
:tx_mbps,
|
:tx_mbps,
|
||||||
:rx_pps,
|
:rx_pps,
|
||||||
:tx_pps,
|
:tx_pps,
|
||||||
|
:rx_errors_per_sec,
|
||||||
|
:tx_errors_per_sec,
|
||||||
|
:rx_dropped_per_sec,
|
||||||
|
:tx_dropped_per_sec,
|
||||||
:create_ip
|
:create_ip
|
||||||
)
|
)
|
||||||
");
|
");
|
||||||
@@ -1125,10 +1163,18 @@ function add_network_usage_log_for_interface(array $iface): void
|
|||||||
':tx_bytes' => $txBytes,
|
':tx_bytes' => $txBytes,
|
||||||
':rx_packets' => $rxPackets,
|
':rx_packets' => $rxPackets,
|
||||||
':tx_packets' => $txPackets,
|
':tx_packets' => $txPackets,
|
||||||
|
':rx_errors' => $rxErrors,
|
||||||
|
':tx_errors' => $txErrors,
|
||||||
|
':rx_dropped' => $rxDropped,
|
||||||
|
':tx_dropped' => $txDropped,
|
||||||
':rx_mbps' => $rxMbps,
|
':rx_mbps' => $rxMbps,
|
||||||
':tx_mbps' => $txMbps,
|
':tx_mbps' => $txMbps,
|
||||||
':rx_pps' => $rxPps,
|
':rx_pps' => $rxPps,
|
||||||
':tx_pps' => $txPps,
|
':tx_pps' => $txPps,
|
||||||
|
':rx_errors_per_sec' => $rxErrorsPerSec,
|
||||||
|
':tx_errors_per_sec' => $txErrorsPerSec,
|
||||||
|
':rx_dropped_per_sec' => $rxDroppedPerSec,
|
||||||
|
':tx_dropped_per_sec' => $txDroppedPerSec,
|
||||||
':create_ip' => $_SERVER['REMOTE_ADDR'] ?? 'cli',
|
':create_ip' => $_SERVER['REMOTE_ADDR'] ?? 'cli',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1152,7 +1198,11 @@ function network_usage_history(int $limit = 240): array
|
|||||||
ROUND(rx_mbps / 8, 4) AS rx_mbytes,
|
ROUND(rx_mbps / 8, 4) AS rx_mbytes,
|
||||||
ROUND(tx_mbps / 8, 4) AS tx_mbytes,
|
ROUND(tx_mbps / 8, 4) AS tx_mbytes,
|
||||||
rx_pps,
|
rx_pps,
|
||||||
tx_pps
|
tx_pps,
|
||||||
|
rx_errors_per_sec,
|
||||||
|
tx_errors_per_sec,
|
||||||
|
rx_dropped_per_sec,
|
||||||
|
tx_dropped_per_sec
|
||||||
FROM network_usage_logs
|
FROM network_usage_logs
|
||||||
WHERE rx_mbps IS NOT NULL
|
WHERE rx_mbps IS NOT NULL
|
||||||
AND tx_mbps IS NOT NULL
|
AND tx_mbps IS NOT NULL
|
||||||
|
|||||||
@@ -167,10 +167,14 @@
|
|||||||
wifi5History: '5G WiFi History',
|
wifi5History: '5G WiFi History',
|
||||||
downloadRxPackets: 'Download / RX Packets',
|
downloadRxPackets: 'Download / RX Packets',
|
||||||
uploadTxPackets: 'Upload / TX Packets',
|
uploadTxPackets: 'Upload / TX Packets',
|
||||||
|
rxErrorsDrops: 'RX Errors / Drops',
|
||||||
|
txErrorsDrops: 'TX Errors / Drops',
|
||||||
downloadLine: 'Download',
|
downloadLine: 'Download',
|
||||||
uploadLine: 'Upload',
|
uploadLine: 'Upload',
|
||||||
rxPacketsLine: 'RX Packets',
|
rxPacketsLine: 'RX Packets',
|
||||||
txPacketsLine: 'TX Packets',
|
txPacketsLine: 'TX Packets',
|
||||||
|
errorsLine: 'Errors',
|
||||||
|
dropsLine: 'Drops',
|
||||||
remaining: 'Remaining',
|
remaining: 'Remaining',
|
||||||
batteryVoltage: 'Battery Voltage',
|
batteryVoltage: 'Battery Voltage',
|
||||||
wifiClients: 'DHCP Clients',
|
wifiClients: 'DHCP Clients',
|
||||||
@@ -373,10 +377,14 @@
|
|||||||
wifi5History: '5G WiFi 이력',
|
wifi5History: '5G WiFi 이력',
|
||||||
downloadRxPackets: '다운로드 / RX 패킷',
|
downloadRxPackets: '다운로드 / RX 패킷',
|
||||||
uploadTxPackets: '업로드 / TX 패킷',
|
uploadTxPackets: '업로드 / TX 패킷',
|
||||||
|
rxErrorsDrops: 'RX 오류 / 드롭',
|
||||||
|
txErrorsDrops: 'TX 오류 / 드롭',
|
||||||
downloadLine: '다운로드',
|
downloadLine: '다운로드',
|
||||||
uploadLine: '업로드',
|
uploadLine: '업로드',
|
||||||
rxPacketsLine: 'RX 패킷',
|
rxPacketsLine: 'RX 패킷',
|
||||||
txPacketsLine: 'TX 패킷',
|
txPacketsLine: 'TX 패킷',
|
||||||
|
errorsLine: '오류',
|
||||||
|
dropsLine: '드롭',
|
||||||
remaining: '잔여 시간',
|
remaining: '잔여 시간',
|
||||||
batteryVoltage: '배터리 전압',
|
batteryVoltage: '배터리 전압',
|
||||||
wifiClients: 'DHCP 클라이언트',
|
wifiClients: 'DHCP 클라이언트',
|
||||||
@@ -2626,6 +2634,114 @@
|
|||||||
c.update('none');
|
c.update('none');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function networkQualityChart(canvasId, rows, errorKey, dropKey) {
|
||||||
|
const canvas = $('#' + canvasId);
|
||||||
|
if (!canvas || typeof Chart === 'undefined') return;
|
||||||
|
|
||||||
|
const { labels, xTickCallback, xGridColor } = timeAxis(rows);
|
||||||
|
const errorValues = rows.map(row => {
|
||||||
|
const value = Number(row[errorKey]);
|
||||||
|
return Number.isFinite(value) ? value : null;
|
||||||
|
});
|
||||||
|
const dropValues = rows.map(row => {
|
||||||
|
const value = Number(row[dropKey]);
|
||||||
|
return Number.isFinite(value) ? value : null;
|
||||||
|
});
|
||||||
|
const scale = dynamicScaleForValues([...errorValues, ...dropValues], { minSpan: 1, padding: 0.2 });
|
||||||
|
const datasets = [
|
||||||
|
{
|
||||||
|
label: t('errorsLine'),
|
||||||
|
data: errorValues,
|
||||||
|
borderColor: '#ef4444',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderWidth: 2.1,
|
||||||
|
pointRadius: 0,
|
||||||
|
tension: 0.2,
|
||||||
|
fill: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('dropsLine'),
|
||||||
|
data: dropValues,
|
||||||
|
borderColor: '#f59e0b',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderWidth: 2,
|
||||||
|
borderDash: [5, 4],
|
||||||
|
pointRadius: 0,
|
||||||
|
tension: 0.2,
|
||||||
|
fill: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
animation: false,
|
||||||
|
interaction: {
|
||||||
|
intersect: false,
|
||||||
|
mode: 'index',
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: true,
|
||||||
|
position: 'bottom',
|
||||||
|
labels: {
|
||||||
|
boxWidth: 18,
|
||||||
|
boxHeight: 2,
|
||||||
|
color: '#8d98aa',
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
displayColors: true,
|
||||||
|
padding: 8,
|
||||||
|
callbacks: {
|
||||||
|
label: item => `${item.dataset.label}: ${formatChartNumber(item.parsed.y, '/s')}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
ticks: {
|
||||||
|
color: '#64748b',
|
||||||
|
maxRotation: 0,
|
||||||
|
autoSkip: false,
|
||||||
|
callback: xTickCallback,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: xGridColor,
|
||||||
|
drawTicks: false,
|
||||||
|
},
|
||||||
|
border: { display: false },
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
min: scale.min,
|
||||||
|
max: scale.max,
|
||||||
|
ticks: {
|
||||||
|
color: '#8d98aa',
|
||||||
|
maxTicksLimit: 4,
|
||||||
|
callback: value => formatChartNumber(value, '/s'),
|
||||||
|
},
|
||||||
|
grid: { color: 'rgba(255,255,255,.045)', drawTicks: false },
|
||||||
|
border: { display: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!state.charts[canvasId]) {
|
||||||
|
state.charts[canvasId] = new Chart(canvas, {
|
||||||
|
type: 'line',
|
||||||
|
data: { labels, datasets },
|
||||||
|
options,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const c = state.charts[canvasId];
|
||||||
|
c.data.labels = labels;
|
||||||
|
c.data.datasets = datasets;
|
||||||
|
c.options = options;
|
||||||
|
c.update('none');
|
||||||
|
}
|
||||||
|
|
||||||
function dynamicScaleForValues(values, options = {}) {
|
function dynamicScaleForValues(values, options = {}) {
|
||||||
const floor = Number(options.floor ?? 0);
|
const floor = Number(options.floor ?? 0);
|
||||||
const ceiling = Number.isFinite(Number(options.ceiling)) ? Number(options.ceiling) : null;
|
const ceiling = Number.isFinite(Number(options.ceiling)) ? Number(options.ceiling) : null;
|
||||||
@@ -2690,12 +2806,20 @@
|
|||||||
const wifi5Rows = networkRowsForIface(networkRows, 'wlan1');
|
const wifi5Rows = networkRowsForIface(networkRows, 'wlan1');
|
||||||
networkChart('netWanRxChart', wanRows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
networkChart('netWanRxChart', wanRows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
||||||
networkChart('netWanTxChart', wanRows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
networkChart('netWanTxChart', wanRows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
||||||
|
networkQualityChart('netWanRxQualityChart', wanRows, 'rx_errors_per_sec', 'rx_dropped_per_sec');
|
||||||
|
networkQualityChart('netWanTxQualityChart', wanRows, 'tx_errors_per_sec', 'tx_dropped_per_sec');
|
||||||
networkChart('netLanRxChart', lanRows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
networkChart('netLanRxChart', lanRows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
||||||
networkChart('netLanTxChart', lanRows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
networkChart('netLanTxChart', lanRows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
||||||
|
networkQualityChart('netLanRxQualityChart', lanRows, 'rx_errors_per_sec', 'rx_dropped_per_sec');
|
||||||
|
networkQualityChart('netLanTxQualityChart', lanRows, 'tx_errors_per_sec', 'tx_dropped_per_sec');
|
||||||
networkChart('netWifi24RxChart', wifi24Rows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
networkChart('netWifi24RxChart', wifi24Rows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
||||||
networkChart('netWifi24TxChart', wifi24Rows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
networkChart('netWifi24TxChart', wifi24Rows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
||||||
|
networkQualityChart('netWifi24RxQualityChart', wifi24Rows, 'rx_errors_per_sec', 'rx_dropped_per_sec');
|
||||||
|
networkQualityChart('netWifi24TxQualityChart', wifi24Rows, 'tx_errors_per_sec', 'tx_dropped_per_sec');
|
||||||
networkChart('netWifi5RxChart', wifi5Rows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
networkChart('netWifi5RxChart', wifi5Rows, 'rx_mbytes', t('downloadLine'), 'rx_pps', t('rxPacketsLine'), '#0ea5e9');
|
||||||
networkChart('netWifi5TxChart', wifi5Rows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
networkChart('netWifi5TxChart', wifi5Rows, 'tx_mbytes', t('uploadLine'), 'tx_pps', t('txPacketsLine'), '#22c55e');
|
||||||
|
networkQualityChart('netWifi5RxQualityChart', wifi5Rows, 'rx_errors_per_sec', 'rx_dropped_per_sec');
|
||||||
|
networkQualityChart('netWifi5TxQualityChart', wifi5Rows, 'tx_errors_per_sec', 'tx_dropped_per_sec');
|
||||||
}
|
}
|
||||||
|
|
||||||
function resizeChartsSoon() {
|
function resizeChartsSoon() {
|
||||||
|
|||||||
@@ -289,6 +289,8 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
|||||||
<div class="chart-grid">
|
<div class="chart-grid">
|
||||||
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWanRxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWanRxChart"></canvas></div></div>
|
||||||
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWanTxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWanTxChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="rxErrorsDrops">RX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWanRxQualityChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="txErrorsDrops">TX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWanTxQualityChart"></canvas></div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -297,6 +299,8 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
|||||||
<div class="chart-grid">
|
<div class="chart-grid">
|
||||||
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netLanRxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netLanRxChart"></canvas></div></div>
|
||||||
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netLanTxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netLanTxChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="rxErrorsDrops">RX Errors / Drops</h3><div class="chart-canvas"><canvas id="netLanRxQualityChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="txErrorsDrops">TX Errors / Drops</h3><div class="chart-canvas"><canvas id="netLanTxQualityChart"></canvas></div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -305,6 +309,8 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
|||||||
<div class="chart-grid">
|
<div class="chart-grid">
|
||||||
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWifi24RxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWifi24RxChart"></canvas></div></div>
|
||||||
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWifi24TxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWifi24TxChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="rxErrorsDrops">RX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWifi24RxQualityChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="txErrorsDrops">TX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWifi24TxQualityChart"></canvas></div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -313,6 +319,8 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
|||||||
<div class="chart-grid">
|
<div class="chart-grid">
|
||||||
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWifi5RxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="downloadRxPackets">Download / RX Packets</h3><div class="chart-canvas"><canvas id="netWifi5RxChart"></canvas></div></div>
|
||||||
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWifi5TxChart"></canvas></div></div>
|
<div class="chart-box wide"><h3 data-i18n="uploadTxPackets">Upload / TX Packets</h3><div class="chart-canvas"><canvas id="netWifi5TxChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="rxErrorsDrops">RX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWifi5RxQualityChart"></canvas></div></div>
|
||||||
|
<div class="chart-box wide"><h3 data-i18n="txErrorsDrops">TX Errors / Drops</h3><div class="chart-canvas"><canvas id="netWifi5TxQualityChart"></canvas></div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user